All Articles

AI Agents for Automated Terraform Code Review — The Future of IaC Quality

How AI agents are automating Terraform code review with security scanning, cost estimation, best practice enforcement, and drift prevention. Covers practical tools, custom LLM pipelines, and CI/CD integration.

DevOpsBoysMar 29, 20267 min read
Share:Tweet

Terraform pull requests are notoriously hard to review. A 200-line change might create 14 resources, modify security groups, change IAM policies, and increase your monthly bill by $500 — and the reviewer has to catch all of that by reading HCL.

Human reviewers miss things. They overlook overly permissive IAM policies, don't calculate cost implications, and can't spot every blast radius issue. AI agents are now filling this gap — automatically reviewing Terraform code for security, cost, best practices, and correctness.

This isn't theoretical. Teams are running LLM-powered review agents in CI/CD today. Here's how.

The Problem with Manual Terraform Review

A typical Terraform PR review requires checking:

  1. Security — Are IAM policies least-privilege? Are S3 buckets public? Are security groups too open?
  2. Cost — How much will this change cost monthly? Is there a cheaper alternative?
  3. Best practices — Is state management proper? Are modules used correctly? Are resources tagged?
  4. Blast radius — What gets destroyed? What gets recreated? Are there unexpected downstream effects?
  5. Compliance — Does this meet organizational policies? SOC 2, HIPAA, PCI requirements?

No human reviewer can consistently check all five dimensions on every PR. And in fast-moving teams, PRs get rubber-stamped with a "LGTM" because the reviewer doesn't have time.

Layer 1: Static Analysis (Pre-AI)

Before adding AI, set up deterministic scanners. These are fast, free, and catch known issues:

tfsec / Trivy

yaml
# .github/workflows/terraform-review.yml
- name: Trivy IaC Scan
  uses: aquasecurity/trivy-action@master
  with:
    scan-type: config
    scan-ref: ./terraform
    severity: HIGH,CRITICAL
    exit-code: 1

Catches: public S3 buckets, unencrypted RDS, wide security group rules, missing logging.

Checkov

yaml
- name: Checkov Scan
  uses: bridgecrewio/checkov-action@master
  with:
    directory: ./terraform
    framework: terraform
    output_format: sarif
    soft_fail: false

Catches: 1000+ built-in policies for AWS, GCP, Azure. CIS benchmarks, SOC 2, HIPAA.

Infracost

yaml
- name: Infracost Cost Estimation
  uses: infracost/actions/setup@v3
  with:
    api-key: ${{ secrets.INFRACOST_API_KEY }}
- run: |
    infracost diff --path=./terraform \
      --format=json \
      --out-file=/tmp/infracost.json
    infracost comment github \
      --path=/tmp/infracost.json \
      --repo=${{ github.repository }} \
      --pull-request=${{ github.event.pull_request.number }} \
      --github-token=${{ secrets.GITHUB_TOKEN }}

Posts a cost breakdown comment on the PR:

Monthly cost will increase by $127.50 (+23%)

+---------------------+--------+----------+
| Resource            | Before | After    |
+---------------------+--------+----------+
| aws_rds_instance    | $150   | $250     |
| aws_instance (x3)   | $200   | $227.50  |
+---------------------+--------+----------+

Layer 2: AI-Powered Review Agent

Static analysis catches known patterns. AI catches everything else — architectural issues, naming inconsistencies, potential race conditions, and suggestions that require understanding context.

Building a Custom Review Agent

python
# terraform_reviewer.py
import subprocess
import json
from anthropic import Anthropic
 
client = Anthropic()
 
def get_terraform_diff() -> str:
    """Get the Terraform changes in the current PR."""
    result = subprocess.run(
        ["git", "diff", "origin/main...HEAD", "--", "*.tf", "*.tfvars"],
        capture_output=True, text=True
    )
    return result.stdout
 
def get_terraform_plan() -> str:
    """Run terraform plan and capture output."""
    subprocess.run(["terraform", "init", "-backend=false"], capture_output=True)
    result = subprocess.run(
        ["terraform", "plan", "-no-color", "-json"],
        capture_output=True, text=True
    )
    return result.stdout
 
def review_terraform(diff: str, plan: str) -> str:
    """Send Terraform changes to Claude for review."""
    prompt = f"""You are a senior infrastructure engineer reviewing a Terraform pull request.
 
Analyze the following Terraform changes and plan output. Provide a review covering:
 
## Security Review
- IAM policies: are they least-privilege? Flag any `*` in actions or resources
- Network security: are security groups, NACLs, or firewall rules too permissive?
- Encryption: are all data stores encrypted at rest and in transit?
- Secrets: are any credentials, API keys, or sensitive values hardcoded?
- Public exposure: are any resources unnecessarily public?
 
## Cost Review
- Identify the most expensive resources being created/modified
- Suggest cheaper alternatives where appropriate (e.g., reserved instances, smaller instance types, S3 storage classes)
- Flag any resources that might scale unexpectedly
 
## Best Practices
- Are resources properly tagged?
- Is the code modular and DRY?
- Are variables used for configurable values?
- Is state management appropriate?
- Are `count` and `for_each` used correctly?
 
## Blast Radius
- What resources are being destroyed or replaced?
- Are there any unexpected cascading changes?
- Is `prevent_destroy` set on critical resources?
 
## Summary
- Overall risk assessment: LOW / MEDIUM / HIGH
- Top 3 issues to address before merge
- Approval recommendation: APPROVE / REQUEST CHANGES / BLOCK
 
---
 
Terraform Diff:
{diff}
 
Terraform Plan Output:
{plan[:50000]}
"""
 
    response = client.messages.create(
        model="claude-sonnet-4-5-20250514",
        max_tokens=4096,
        messages=[{"role": "user", "content": prompt}]
    )
    return response.content[0].text
 
 
def post_review_comment(review: str, pr_number: str):
    """Post the review as a PR comment."""
    import os
    subprocess.run([
        "gh", "pr", "comment", pr_number,
        "--body", f"## AI Terraform Review\n\n{review}"
    ], env=dict(os.environ))
 
 
if __name__ == "__main__":
    import sys
 
    diff = get_terraform_diff()
    if not diff.strip():
        print("No Terraform changes detected.")
        sys.exit(0)
 
    plan = get_terraform_plan()
 
    print("Running AI review...")
    review = review_terraform(diff, plan)
 
    pr_number = sys.argv[1] if len(sys.argv) > 1 else None
    if pr_number:
        post_review_comment(review, pr_number)
        print(f"Review posted to PR #{pr_number}")
    else:
        print(review)

GitHub Actions Integration

yaml
# .github/workflows/ai-terraform-review.yml
name: AI Terraform Review
on:
  pull_request:
    paths:
      - 'terraform/**'
      - '*.tf'
 
jobs:
  ai-review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - uses: hashicorp/setup-terraform@v3
 
      - name: Install dependencies
        run: pip install anthropic
 
      - name: Run AI Review
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: python terraform_reviewer.py ${{ github.event.pull_request.number }}

Now every Terraform PR gets an automated AI review within minutes.

Layer 3: Policy-as-Code with AI Reasoning

Combine OPA/Rego policies with AI for nuanced enforcement:

python
def check_with_context(violation: dict, diff: str) -> dict:
    """Use AI to add context to policy violations."""
    prompt = f"""A Terraform policy check found this violation:
 
Rule: {violation['rule']}
Resource: {violation['resource']}
Message: {violation['message']}
 
Here's the full Terraform diff for context:
{diff}
 
Analyze this violation:
1. Is this a genuine issue or a false positive? (Consider the resource type and use case)
2. What's the severity? (Critical / High / Medium / Low)
3. How should it be fixed? (Provide the corrected HCL code)
4. What's the business risk if not fixed?
 
Be concise and practical."""
 
    response = client.messages.create(
        model="claude-sonnet-4-5-20250514",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}]
    )
 
    result = dict(violation)
    result["ai_analysis"] = response.content[0].text
    return result

This turns a dry policy violation like "S3 bucket missing encryption" into actionable context: "This bucket stores user uploads with PII. AES-256 encryption is required for GDPR compliance. Add server_side_encryption_configuration block."

Existing Tools to Use Today

1. Spacelift AI

Spacelift's built-in AI reviews Terraform plans and suggests changes:

  • Explains plan diffs in plain English
  • Suggests security improvements
  • Estimates cost impact
  • Integrates with OPA policies

2. Digger + LLM

Digger (open-source Terraform CI/CD) supports LLM-powered plan summaries:

yaml
# digger.yml
projects:
  - name: production
    dir: terraform/production
    ai_summary: true  # LLM summarizes plan changes

3. Atlantis + Custom Webhooks

Extend Atlantis with a post-plan webhook that sends the plan to an LLM:

yaml
# atlantis.yaml
workflows:
  default:
    plan:
      steps:
        - init
        - plan
        - run: python /scripts/ai-review.py $PLANFILE

Guardrails for AI Reviews

AI review agents are powerful but need guardrails:

1. AI recommends, humans decide — AI reviews should be advisory, not blocking. A human must approve the final merge.

2. Don't send secrets to the API — Sanitize .tfvars and state files before sending to an LLM. Strip any password, secret, token, or key values.

3. Track accuracy — Log AI review suggestions and whether they were accepted or rejected. Use this feedback to improve prompts.

4. Cost control — Sending large Terraform diffs to an LLM costs $0.05-0.50 per review. For high-volume repos, implement caching and deduplication.

5. Combine with deterministic tools — AI complements tfsec/Checkov/Infracost, it doesn't replace them. Static analysis is faster, cheaper, and more reliable for known patterns.

The Review Pipeline

The ideal Terraform review pipeline:

PR opened →
  Layer 1: tfsec + Checkov (security scanning)     → 30 seconds
  Layer 1: Infracost (cost estimation)              → 1 minute
  Layer 2: AI agent review (comprehensive analysis) → 2 minutes
  Layer 3: Policy-as-code with AI reasoning         → 1 minute
→ All results posted as PR comments
→ Human reviewer sees comprehensive analysis
→ Review time drops from 30 minutes to 5 minutes

For building Terraform skills that make AI review outputs actionable, KodeKloud's Terraform courses cover IaC patterns, security, and state management in depth.


The best Terraform review catches what humans miss. AI agents don't get tired, don't skip steps, and don't LGTM without reading the code.

Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments