Modern QA2026Integrating AI Review into CI — tiles
Log inJoin
72 / 75 · 08 Infrastructure as Code Testing · AI Agents Reviewing Infrastructure Code← prev⊞ allnext →☰ Read as one page

13.4Integrating AI Review into CI

GitHub Actions Workflow

# .github/workflows/iac-review.yml
name: AI Infrastructure Review
on:
  pull_request:
    paths:
      - 'terraform/**'
      - 'k8s/**'
      - 'Dockerfile*'

jobs:
  ai-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate Terraform plan
        run: |
          cd terraform/
          terraform init
          terraform plan -out=tfplan
          terraform show -json tfplan > tfplan.json

      - name: Static analysis
        run: |
          checkov -d ./terraform/ -o json > checkov-results.json
          trivy config ./terraform/ --format json > trivy-results.json

      - name: AI review of changes
        run: |
          # Combine plan + static analysis for AI review
          python scripts/ai_iac_review.py \
            --plan terraform/tfplan.json \
            --checkov checkov-results.json \
            --trivy trivy-results.json \
            --output review-comment.md

      - name: Post review to PR
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const body = fs.readFileSync('review-comment.md', 'utf8');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: body
            });

The AI Review Script

# scripts/ai_iac_review.py
import json
import argparse
import os
from anthropic import Anthropic

def load_json(path):
    with open(path) as f:
        return json.load(f)

def build_review_prompt(plan, checkov_results, trivy_results):
    """Build a structured prompt for AI review."""

    # Summarize the plan
    changes = plan.get("resource_changes", [])
    creates = [c["address"] for c in changes if "create" in c["change"]["actions"]]
    updates = [c["address"] for c in changes if "update" in c["change"]["actions"]]
    destroys = [c["address"] for c in changes if "delete" in c["change"]["actions"]]

    # Summarize static analysis findings
    checkov_failures = [
        r for r in checkov_results.get("results", {}).get("failed_checks", [])
    ]
    trivy_findings = trivy_results.get("Results", [])

    prompt = f"""Review this Terraform infrastructure change:

## Plan Summary
- Resources to create: {len(creates)} ({', '.join(creates[:10])})
- Resources to update: {len(updates)} ({', '.join(updates[:10])})
- Resources to destroy: {len(destroys)} ({', '.join(destroys[:10])})

## Full Plan
```json
{json.dumps(plan, indent=2)[:10000]}

Checkov Findings ({len(checkov_failures)} failures)

{json.dumps(checkov_failures[:20], indent=2)}

Trivy Findings

{json.dumps(trivy_findings[:20], indent=2)}

Provide a structured review with severity ratings."""

return prompt

def main(): parser = argparse.ArgumentParser() parser.add_argument("--plan", required=True) parser.add_argument("--checkov", required=True) parser.add_argument("--trivy", required=True) parser.add_argument("--output", required=True) args = parser.parse_args()

plan = load_json(args.plan)
checkov = load_json(args.checkov)
trivy = load_json(args.trivy)

prompt = build_review_prompt(plan, checkov, trivy)

client = Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    messages=[{"role": "user", "content": prompt}],
    system="You are a senior infrastructure security engineer. Review the Terraform plan and static analysis results. Provide actionable findings with severity ratings.",
)

review = response.content[0].text

with open(args.output, "w") as f:
    f.write("## AI Infrastructure Review\n\n")
    f.write(review)
    f.write("\n\n---\n*Generated by AI review pipeline*")

if name == "main": main() ```