Introduction: The Allure of AI‑Assisted IaC
Large language models (LLMs) have become commonplace in DevOps tooling. Many cloud providers now embed AI in their IaC consoles, offering “one‑click” plan previews that claim to predict the impact of a Terraform change. While the convenience is tempting, the technology is still prone to hallucinations, incomplete context, and subtle policy violations. This article explains why you should not hand over the final gate‑keeping of production infrastructure to an AI, and walks you through a reproducible, auditable verification pipeline that keeps human oversight in the loop.
What the AI‑Generated Preview Looks Like
A typical AI‑enhanced console will display a diff similar to the native terraform plan output, but it is generated from a prompt rather than a real execution. The preview often omits provider‑specific warnings, skips terraform validate checks, and may suggest resources that do not exist in the target workspace. Below is a fabricated example:
╷
│ Warning: The attribute "aws_vpc.id" is unknown, so it cannot be used.
│
│ on main.tf line 12, in resource "aws_subnet" "private":
│ 12: vpc_id = aws_vpc.main.id
│
╷
│ Plan: 3 to add, 0 to change, 0 to destroy.
│
+ resource "aws_vpc" "main" {
+ cidr_block = "10.0.0.0/16"
+ }
+
+ resource "aws_subnet" "private" {
+ vpc_id = "vpc-0abcd1234ef567890"
+ cidr_block = "10.0.1.0/24"
+ availability_zone = "us-east-1a"
+ }
The AI‑generated diff pretends that the VPC ID is known, even though the provider would flag it as unknown until after a real plan run. This is a classic hallucination that can lead to downstream failures or, worse, unnoticed security gaps.
Hidden Risks of Blindly Accepting AI Previews
1. Policy Drift. AI does not understand your organization’s Sentinel or Open Policy Agent (OPA) policies. A suggested change may violate cost caps, tag conventions, or encryption requirements without any warning.
2. State Desynchronization. AI lacks access to the remote state backend. It may produce a plan that assumes resources exist locally but are missing in the shared state, leading to duplicate resources or orphaned infrastructure.
3. Credential Leakage. Some AI services request a copy of your Terraform files for context. Uploading files that contain raw provider credentials or secrets can inadvertently expose them to third‑party models.
4. Compliance Auditing Gaps. Regulatory audits require an immutable record of who approved a change and why. An AI‑generated preview does not produce a signed approval artifact, breaking the audit trail.
Building a Safe Verification Pipeline
The following tutorial shows how to integrate three open‑source safeguards into a GitHub Actions workflow:
- Run
terraform initandterraform validateagainst the actual configuration. - Execute
terraform plan -out=plan.outand store the binary plan artifact. - Scan the plan with
tfsecfor security misconfigurations. - Apply Sentinel policies (or OPA) to the generated plan.
- Require manual approval before
terraform applyproceeds.
# .github/workflows/terraform-verify.yml
name: Terraform Verify & Apply
on:
pull_request:
paths:
- '**/*.tf'
workflow_dispatch:
jobs:
verify:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: "1.6.0"
- name: Terraform Init
run: terraform init -backend-config="bucket=my-terraform-state"
- name: Terraform Validate
run: terraform validate
- name: Generate Plan
id: plan
run: |
terraform plan -out=plan.out
terraform show -json plan.out > plan.json
continue-on-error: false
- name: Upload Plan Artifact
uses: actions/upload-artifact@v3
with:
name: tf-plan
path: plan.out
- name: Run tfsec
uses: aquasecurity/tfsec-action@v1
with:
soft_fail: false
- name: Sentinel Policy Check (optional)
if: ${{ env.SENTINEL_ENABLED == 'true' }}
run: |
sentinel test -run=policy.hcl -input=plan.json
- name: Request Manual Approval
uses: peter-evans/slash-command-dispatch@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-type: pull-request
command: "/approve"
reaction: "+1"
timeout: 86400
apply:
needs: verify
if: github.event_name == 'workflow_dispatch' && github.event.inputs.approved == 'true'
runs-on: ubuntu-latest
steps:
- name: Download Plan Artifact
uses: actions/download-artifact@v3
with:
name: tf-plan
path: .
- name: Apply Plan
run: terraform apply -auto-approve plan.out
The workflow above does not rely on any AI‑generated preview. Instead, it uses the real Terraform engine to produce an authoritative plan, then runs static analysis (tfsec) and policy enforcement before any human can approve the change. The Request Manual Approval step ensures an audit‑ready signature from a designated reviewer.
Integrating OPA for Fine‑Grained Policy Control
If your organization prefers OPA over Sentinel, the same plan JSON can be evaluated with Rego rules. Below is a minimal example that forbids any aws_instance without an encrypted = true flag.
# policies/instance_encryption.rego
package terraform.policy
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_instance"
not resource.change.after.encrypted
msg := sprintf("Instance %s must have encryption enabled", [resource.address])
}
Add an OPA step to the workflow:
- name: OPA Policy Check
run: |
opa eval -i plan.json -d policies/instance_encryption.rego "data.terraform.policy.deny"
If the evaluation returns any messages, the job fails, preventing the plan from reaching the approval stage.
Why This Matters: Real‑World Incident Example
In Q1 2026, a fintech startup enabled an AI‑assisted preview feature on its cloud console. The AI suggested a new S3 bucket without server‑side encryption. Because the team trusted the preview, the bucket was provisioned with default settings, exposing customer PII for weeks before a manual audit caught it. The breach resulted in regulatory fines and loss of customer trust. A robust verification pipeline as described above would have flagged the missing encryption before the resource ever touched production.
Security and Best Practices
Never store provider credentials in the repository. Use GitHub Secrets or a dedicated secret manager and reference them via TF_VAR_* environment variables.
Enable remote state locking. Configure your backend (e.g., AWS DynamoDB for S3) to prevent concurrent modifications.
Version‑pin all providers and modules. Add a required_version and required_providers block to avoid accidental upgrades triggered by AI suggestions.
Audit AI usage. If you must use AI assistance, keep a separate log of prompts and responses, and never feed raw Terraform files containing secrets to the model.
“Automation is only as good as the assumptions you bake into it. Human review remains the final safeguard.”
Conclusion
AI‑generated Terraform plan previews are attractive,