Coding agents that can terraform apply are one prompt injection away from opening your account. The unfair advantage is not “better prompts for HCL” — it is plan-diff gates: every model-proposed change must produce a plan artifact, pass OPA/Conftest, and get human approval before apply. Never auto-apply IAM, network, or KMS from an unattended agent.
⚡ TL;DR: Agent writes
.tf→ CI runsterraform plan -out→ OPA checks the JSON plan → humans approve high-risk deltas → only thenapply. Banapplyfrom agent shells. Combine with Claude Code hooks for risky shell and Cursor CDK wildcard rules.
Force plan artifacts, not vibes
# modules/ai_gate/main.tf — illustrative boundaries
resource "aws_iam_policy" "svc" {
name = var.policy_name
policy = data.aws_iam_policy_document.svc.json
}
# ❌ Agent anti-pattern
# resource "aws_iam_policy" "svc" {
# policy = jsonencode({
# Statement = [{ Effect = "Allow", Action = "*", Resource = "*" }]
# })
# }
# ci/terraform-agent-pr.sh
set -euo pipefail
terraform init -backend-config=backend.hcl
terraform plan -input=false -out=tfplan.bin
terraform show -json tfplan.bin > tfplan.json
# ✅ OPA on the plan, not on HCL text alone
conftest test tfplan.json -p policy/terraform
# ❌ terraform apply in the agent tool allowlist
OPA policies that catch AI favorites
# policy/terraform/no_wildcards.rego
package terraform.aws
deny[msg] {
some change in input.resource_changes
change.type == "aws_iam_policy"
after := change.change.after
contains(after.policy, `"Action":"*"`)
msg := sprintf("wildcard Action in %s", [change.address])
}
deny[msg] {
some change in input.resource_changes
change.type == "aws_security_group_rule"
change.change.after.cidr_blocks[_] == "0.0.0.0/0"
change.change.after.to_port == 22
msg := "SSH open to world"
}
deny[msg] {
some change in input.resource_changes
change.type == "aws_kms_key"
change.change.actions[_] == "delete"
msg := "KMS key deletion requires break-glass label"
}
✅ Plan JSON is the source of truth for policy.
❌ Regex on .tf files that miss jsonencode and modules.
Human approval for blast-radius classes
| Change class | Auto-merge after green plan? | Required |
|---|---|---|
| Tags / dashboards | Yes | Plan + OPA |
| IAM / SG / NACL | No | +2 reviewers |
| KMS / Org SCPs | No | Break-glass + change ticket |
| State rm / destroy | No | Explicit DESTROY_OK label |
# .github/workflows/tf-agent.yml
jobs:
plan:
if: contains(github.event.pull_request.labels.*.name, 'ai-terraform')
steps:
- run: ./ci/terraform-agent-pr.sh
- uses: actions/upload-artifact@v4
with: { name: tfplan, path: tfplan.bin }
apply:
needs: plan
environment: production-terraform # ✅ GitHub env protection rules
if: github.event.review.state == 'approved'
steps:
- run: terraform apply -input=false tfplan.bin
Hook agent shells so terraform apply never runs locally in CI agents — see Claude Code hooks.
Closing checklist
✅ Dos
– ✅ Always plan -out + show -json for agent PRs
– ✅ OPA/Conftest on plan JSON for IAM, network, KMS
– ✅ Environment-protected apply jobs
– ✅ Label-gated destroy and state surgery
– ✅ Ban apply from agent tool allowlists
❌ Don’ts
– ❌ Don’t auto-apply from unattended coding agents
– ❌ Don’t trust HCL lint alone for wildcards
– ❌ Don’t let agents hold long-lived cloud admin keys
– ❌ Don’t skip human review on IAM/SG/KMS deltas
– ❌ Don’t ignore AI coding VPC hygiene for plan runners
Related reading
- Claude Code Hooks: Gate Risky Shell Commands Before CI Runs
- Cursor Rules for AWS CDK: Stop AI From Inventing IAM Wildcards
- AI Coding in VPC: Private Bedrock Endpoints and Secret Hygiene
- AI Code Review Bots: IAM, Secrets, and Least-Privilege Pipelines
Last updated on September 11, 2026
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.

Pingback: Bedrock Guardrail Metrics: False Positives That Block Honest Deploys - CheatCoders