BXUP Track progress & test yourself — free
DevOps / SRE / Platform · Module · ~14 min read
DEVOPS / SRE / PLATFORM · MODULE

AI-Assisted IaC & Pipelines with Verification Gates

Infrastructure code is the one AI output that machines can check before a human ever reads it. This module makes validate → plan → policy → cost a reflex, so every AI-drafted module arrives at review with the mechanical failure classes already caught and your attention free for the two that aren't.

Meera's assistant produced the S3 module in eleven seconds. Clean HCL, sensible variable names, a versioning block, a lifecycle rule, tags threaded through — the kind of output that makes even a skeptic quiet for a moment. It also contained aws_s3_bucket_lifecycle_rule, a resource that does not exist; an inline acl = "private" the AWS provider deprecated two major versions ago; and a force_destroy = true nobody asked for, sitting one typo away from erasing the bucket of checkout-api logs it was meant to hold.

None of this is visible by reading. It reads right — that is exactly the point, and exactly the danger. Meera, of all people, had almost pasted it in; she caught the lifecycle resource only because she'd fought that same error the week before.

"This is why I keep it away from prod," she told Divya. Divya, reading over her shoulder, drew the opposite lesson: not a reason to ban the tool, but a reason the tool needs gates the machine runs — because human eyes are precisely what these failure classes are optimized to slip past.

Here is the good news, and the reason IaC is where AI assistance earns its keep despite all of that. Infrastructure code is where AI assistance in ops gets real leverage first — and where the trust map from M1 earns its keep. Terraform modules, Kubernetes manifests, and CI pipelines are exactly the artifact class the Common Core called cheap to generate and expensive to be wrong about: declarative, convention-heavy, boilerplate-rich (AI's home turf), yet executed with credentials that can reshape an estate. The good news is structural: IaC is more gateable than almost any other AI output, because the ecosystem already ships deterministic verifiers — terraform validate and plan, schema validators, policy scanners, cost estimators — that catch AI failure modes mechanically, before human review even begins.

This module builds that gate chain as a reflex: you will draft infrastructure with AI at generate-only trust, run every draft through an always-on validate → plan → policy → cost pipeline, learn the specific ways models hallucinate HCL so you recognize them on sight, apply the same loop to Kubernetes manifests with kubeconform and kube-score, use AI for CI failure diagnosis with calibrated trust per failure class, and deploy AI review on infra PRs the only way the evidence supports: advisory, never blocking. Everything here runs on free OSS tooling — the gate chain costs nothing but discipline.

Key Takeaway:

In AI-assisted IaC, the verification chain is the skill — anyone can prompt a module into existence; the engineer who wires validate → plan → policy → cost so that nothing unverified can reach review is the one who ships AI speed without shipping AI risk.

What You'll Learn

  • HCL hallucination failure modesinvented resource types, invented attributes, stale provider syntax, and why plausibility is worthless in IaC
  • The always-run gate chainterraform validate → plan → Checkov → Infracost, wired as pre-commit and CI, with worked configs
  • Contract-first promptingpatterns for drafting Terraform, K8s manifests and pipelines that give the gates something clean to catch
  • The kubeconform + kube-score loopschema validation plus best-practice linting for AI-generated Kubernetes YAML
  • CI failure diagnosisusing AI on broken pipelines, with trust calibrated by failure class
  • Advisory AI review for infra PRsops-specific rubrics, PR-comment placement, and why blocking is the wrong design

How Models Hallucinate Infrastructure Code

The Common Core taught hallucinated APIs as a general failure mode. In HCL it has a specific, well-documented shape: research accompanying the TerraFormer work (January 2026) found that even state-of-the-art models hallucinate Terraform resource types and attributes — emitting blocks that read fluently and do not exist. This is worth internalizing as a taxonomy, because each failure mode has a different gate that catches it:

  • Invented resource types and data sources. A plausible-sounding aws_s3_bucket_lifecycle_rule where the real resource is aws_s3_bucket_lifecycle_configuration — the exact ghost in Meera's eleven-second module. Caught by terraform validate — free and instant.
  • Invented or misplaced attributes. Real resource, fictional argument; or an argument that belongs in a nested block placed at top level. Also caught by validate — this is why validate runs first even though it feels trivial.
  • Stale provider syntax. The most insidious class, because it was once correct: training data is full of AWS provider v3 patterns (inline acl on buckets, deprecated arguments) that v5 rejects or — worse — silently ignores. Sometimes caught by validate, sometimes only visible in plan output or deprecation warnings. Pin provider versions and tell the model which one you use.
  • Valid-but-wrong semantics. Everything the syntax gates cannot see: a security group open to 0.0.0.0/0, encryption omitted, force_destroy = true on a stateful resource, an instance type ten times your budget. Valid, plannable, and dangerous — this is what the policy and cost gates exist for.
  • Cross-resource incoherence. References that resolve but mislead: a subnet in the wrong tier, an IAM policy attached to the wrong principal, count/for_each logic that plans clean and creates 40 resources where you meant 4. Caught only by reading the plan — the human gate.

The ordering matters: each gate is cheaper than the next, and each failure mode falls to the earliest gate that can see it. The taxonomy also explains why "it looks right" is worth nothing in IaC — four of the five classes are specifically optimized, by the model's training objective, to look right.

Warning

Stale-syntax hallucinations are the class most likely to survive careless review, because the reviewer half-remembers the old syntax too — always pin provider versions in the prompt and in required_providers, and treat deprecation warnings in plan output as review findings, not noise.

The Gate Chain: validate → plan → policy → cost

The rule this module exists to install: AI-drafted IaC never reaches human review without passing the full chain. Not because humans are careless, but because human attention is the scarcest gate — spending it on typo-class errors that validate catches for free is waste, and arriving at review with mechanical checks green means review can focus on the two failure classes only humans catch.

The chain, as a Makefile you can drop into any Terraform repo today:

# Gate chain for AI-assisted Terraform. Run: make gate
.PHONY: gate validate plan policy cost

gate: validate plan policy cost
	@echo "All gates passed - ready for human review."

validate:
	terraform fmt -check -recursive
	terraform init -backend=false -input=false
	terraform validate

plan:
	terraform plan -input=false -out=tfplan.bin
	terraform show -json tfplan.bin > tfplan.json

policy:
	checkov -d . --quiet --compact
	checkov -f tfplan.json --quiet --compact   # plan-aware checks

cost:
	infracost breakdown --path . --format table
	infracost diff --path . --compare-to infracost-base.json || true

And the same chain as CI, where it belongs permanently (GitHub Actions shown; the GitLab translation is mechanical):

name: iac-gates
on:
  pull_request:
    paths: ["infra/**"]
jobs:
  gates:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - name: Validate
        working-directory: infra
        run: |
          terraform fmt -check -recursive
          terraform init -backend=false -input=false
          terraform validate
      - name: Plan
        working-directory: infra
        run: terraform plan -input=false -out=tfplan.bin
      - name: Policy scan (Checkov)
        uses: bridgecrewio/checkov-action@v12
        with:
          directory: infra
          quiet: true
      - name: Cost estimate (Infracost)
        uses: infracost/actions/setup@v3
        with:
          api-key: ${{ secrets.INFRACOST_API_KEY }}
      - name: Post cost diff to PR
        run: |
          infracost breakdown --path infra --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 }} --behavior update

Three design notes carry the chain:

  • The plan is the review artifact, not the HCL — what you approve is "3 to add, 1 to change, 0 to destroy" and the specifics beneath it. Any nonzero destroy count on a stateful resource escalates review regardless of how the diff reads.
  • Checkov runs twiceon source for static misconfigurations, and on the plan JSON for checks that need resolved values. When Checkov flags something, AI's role is explainer (Level 1 on your M1 map): "explain CKV_AWS_144 and show the minimal fix for this module" is a high-win prompt; the scanner remains the source of truth, and suppressions (checkov:skip) require a written justification in the code.
  • The cost gate is a trust-map insight in disguiseAI has no idea what anything costs, and cost is invisible in both syntax and policy. Infracost's PR comment turns "the AI quietly chose db.r6g.4xlarge" from a month-end surprise into a review-time conversation.
Pro Tip

Keep a defect log the first month you run the chain — one line per AI error each gate catches, classified against the taxonomy above; after twenty entries you will know your assistant's personal failure signature and your prompts will improve to match.

Note

The whole chain is free — Terraform/OpenTofu, Checkov, and kubeconform are OSS, and Infracost's CLI is free for this use — so "we don't have budget for AI safety tooling" is not a real objection in IaC.

Drafting with AI: Prompts That Give Gates Clean Input

With gates in place, generation can be fast and loose — but a disciplined prompt still saves cycles, because every gate failure is a round trip. The pattern that works for Terraform is contract-first prompting: state versions, module shape, and constraints; let the model fill the interior.

Draft a Terraform module for an S3 bucket for application logs.
Constraints:
- Terraform >= 1.7, AWS provider ~> 5.0 (use current v5 resource
  patterns - separate versioning/encryption/lifecycle resources,
  no deprecated inline arguments)
- Inputs: bucket_name_prefix, retention_days (default 90), tags
- Requirements: versioning on, SSE-KMS with a key created in the
  module, all public access blocked, lifecycle rule to expire
  objects after retention_days, no force_destroy anywhere
- Outputs: bucket_arn, kms_key_arn
Emit only files: main.tf, variables.tf, outputs.tf. I will run
validate, plan, Checkov, and Infracost on the result - prefer
being explicit over being clever.

Then run make gate and feed failures back verbatim — "Checkov flags CKV_AWS_145 on the bucket; fix without suppressing" — rather than hand-patching, so the conversation keeps the full context. Two or three loops typically converge. The same contract-first shape applies to pipeline authoring ("GitHub Actions workflow, ubuntu-latest, needs id-token: write for OIDC to AWS, no long-lived keys") and to pipeline migration, this module's other high-frequency services-company task. For Jenkins-to-Actions migration, the discipline is a parity harness, not trust: run both pipelines on the same commits, diff artifacts, test reports, and versions programmatically, and cut over only when the diff is empty or every delta is explained in writing. AI does the transpilation in minutes; the harness is what makes the minutes safe — the exact generate-fast/verify-mechanically trade this module keeps making.

Kubernetes Manifests: The kubeconform + kube-score Loop

AI-generated Kubernetes YAML fails in the same taxonomy as HCL — invented fields, stale apiVersions, valid-but-unwise defaults — but Kubernetes gives you an even cheaper gate: the API schema itself. The loop is kubeconform for "is this a valid object?" and kube-score for "is this a good object?", wired so generated YAML cannot be applied, or even committed, unvalidated:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: kubeconform
        name: kubeconform (schema validation)
        entry: kubeconform -strict -summary
          -kubernetes-version 1.30.0
        language: system
        files: ^k8s/.*\.ya?ml$
      - id: kube-score
        name: kube-score (best-practice lint)
        entry: kube-score score --output-format ci
        language: system
        files: ^k8s/.*\.ya?ml$

Pin -kubernetes-version to your real cluster version — stale-apiVersion hallucinations (the extensions/v1beta1 ghosts of training data) are invisible against "latest" but caught instantly against your actual version. kube-score then catches the valid-but-unwise class: no resource limits, no probes, single replica behind a PDB, latest image tags. Expect AI-drafted manifests to fail kube-score on first pass almost every time — not because models are bad at YAML, but because minimal examples dominate training data and production hygiene (probes, limits, securityContext, PDBs) is exactly what minimal examples omit. That makes the fix prompt formulaic: paste the kube-score output and require a clean re-emit. As in Terraform, the loop converges in two or three rounds, and the pre-commit wiring means the converged state is the only state that can enter the repo. For clusters you control, the same pair runs in CI against kind for a full dry-run apply — the free path this track's labs use.

Remember:

kubeconform answers "will the API server accept this?"; kube-score answers "will you regret it at 3 a.m.?" — AI-generated manifests routinely pass the first and fail the second, which is precisely why you run both.

CI Failure Diagnosis: Trust by Failure Class

Diagnosing broken pipelines is a Level 1–2 task on your trust map and one of the highest-toil-value AI uses in this module — CI-native assistants (GitLab Duo's root-cause analysis, Copilot in Actions) and paste-the-log workflows both work. But calibration varies sharply by failure class, and knowing the pattern is the skill:

  • Dependency and version failuresAI's best class. The error is textual, the cause is usually in the log, and suggested pins/upgrades are cheap to test.
  • Cache and environment failuresgood, with a caveat: AI will confidently propose cache-busting as a fix when the cache is a symptom; make it state why the cache is stale before you accept.
  • Secret and permission failuresuseful for decoding error shapes (OIDC trust-policy mismatches, token scopes), but logs are deliberately redacted here, so AI reasons from less information than it appears to have. Verify against the actual IAM/settings surface, and never paste unredacted secret-adjacent logs into external tools — on client engagements, this is exactly where your MSA's data rules bind (redact first, or use the client-sanctioned tenancy).
  • Flaky teststhe trap class. Given one failing run, AI produces a plausible root cause for what is actually nondeterminism; the honest answer lives in history, not in a single log. Route the question accordingly: give the model ten runs' pass/fail records and ask for a flake-probability ranking and quarantine proposal — structured analysis over data, not vibes over one traceback — with the quarantine PR human-merged.

A diagnosis prompt that enforces the discipline across all classes:

Here is a failed CI log (attached) and the diff of the triggering
commit. Produce: (1) top 3 ranked hypotheses with a confidence
each, (2) for each, the exact log line(s) supporting it, (3) the
cheapest command or check that would confirm or kill each
hypothesis. Do not propose fixes yet.

Requiring cited log lines and a disconfirming check per hypothesis converts the model from oracle to hypothesis generator — the same shape M3 uses for incident investigation, learned here where the blast radius is only a red pipeline.

Advisory AI Review for Infra PRs

The last gate is the most tempting to over-build. Stack Overflow 2025 found a majority of developers reject fully-AI-driven code review — and for infra PRs the rejection is correct as a matter of design, not sentiment: review is an accountability transfer, and accountability needs a human name on it (the same reason Coinbase's aggressive AI mandate still requires human review on every line). The placement that works is advisory — AI reviews every infra PR and posts findings as comments; a human decides what matters; nothing AI-only ever blocks a merge.

What makes ops-flavored AI review genuinely useful is the rubric. Generic "review this code" produces style noise; an ops rubric aims the model at what infra reviewers actually miss when tired:

Review this Terraform/K8s diff as an infra reviewer. Score ONLY:
1. BLAST RADIUS - resources whose change forces replacement or
   touches shared/stateful infrastructure; flag every "destroy"
   or "replace" implication.
2. SECURITY - IAM widening, public exposure, encryption changes,
   secret handling, security-group deltas.
3. COST - new resources or sizing changes with material spend;
   estimate direction, not exact figures.
4. REVERSIBILITY - can this change be cleanly rolled back? Name
   anything that cannot.
Output: one finding per line as {severity: HIGH|MED|LOW, area,
file:line, one-sentence rationale}. Max 8 findings, no style
comments. If nothing qualifies in an area, print "AREA: clean".

Capping findings and banning style commentary is load-bearing: an AI reviewer that posts twenty nitpicks trains humans to scroll past it, and the one HIGH that mattered scrolls past too. Measure your bot like any alert source — track precision (findings a human acted on / findings posted) monthly, and tune the rubric when precision sags; lab-05 does exactly this against PRs with known seeded issues. Position in the chain matters too: the advisory review runs after the mechanical gates, so it never wastes its findings budget on what Checkov already caught. And the finding categories are not accidental — blast radius, security, cost, reversibility are your M1 map axes, applied per-diff. The AI reviewer is, in the end, a trust-map query answered automatically for every PR: what here would change this change's placement?

Exam Tip

Assessment scenarios probe the advisory-versus-blocking distinction directly — if a design makes an LLM's judgment the sole thing standing between a merge and production, the design is wrong regardless of the model's quality; deterministic gates block, AI advises, humans decide.

Pro Tip

Your first 15 minutes: the next time an assistant hands you a Terraform module, run make gate before you read a single line — let validate → plan → policy → cost speak first, so your scarce attention lands only on the two failure classes the machine cannot see. That reflex is the whole chapter; Meera's near-paste is what it prevents.

Check yourself: Your assistant emits a Terraform module that terraform validate and terraform plan both pass cleanly. Why is "the mechanical gates are green" still not enough to approve it — and which two failure classes are now your personal responsibility?

▸Show answeroptional deep dive — click to expand

Validate and plan catch the syntax-level classes — invented resource types, invented or misplaced attributes, and some stale syntax. They cannot see the two semantic classes: valid-but-wrong semantics (a 0.0.0.0/0 ingress, force_destroy = true on a stateful resource, a db.r6g.4xlarge nobody costed) and cross-resource incoherence (count/for_each that plans clean and creates 40 resources where you meant 4). Green gates mean human review can now focus on exactly those two — by reading the plan itself — not that review is finished. "It looks right" is worth nothing in IaC precisely because four of the five classes are optimized, by the model's training objective, to look right.

Exercises

  1. Build the chain. Wire the full Makefile and CI gate chain into a Terraform repo (any sandbox module). Prompt an assistant for the S3-logs module using the contract-first prompt, run make gate, and log every failure against the five-class hallucination taxonomy. Deliverable: the passing repo plus your classified defect log.
  2. Hallucination hunt. Ask your assistant for a Terraform module using a provider you know well, without pinning versions in the prompt. Find at least one stale-syntax or invented-attribute error, identify which gate catches it, then re-prompt with versions pinned and compare. Write three sentences on what the delta teaches about prompt contracts.
  3. Manifest convergence. Generate a Deployment + Service + HPA + PDB set for a demo app by prompt; run the kubeconform + kube-score pre-commit loop; record how many rounds to convergence and which kube-score checks failed on round one. Compare your round-one failures against a colleague's (or a second model's) — the overlap is the training-data signature this module described.
  4. Failure-class calibration. Take five real failed CI runs from your history (or the lab-03 set): one dependency, one cache/environment, one secrets/permissions, one flaky, one of your choice. Run the ranked-hypotheses prompt on each. Score per class: was the top hypothesis right, and did the cited log lines actually support it? Deliverable: your personal trust-by-failure-class table.
  5. Rubric review dry run. Run the ops review rubric against three of your team's recently merged infra PRs. Count: findings posted, findings that would have changed the merge conversation, findings that are noise. If precision is below half, rewrite one rubric line to fix the worst noise source and rerun.

Your playbooks & labs

This module's companion playbooks cover the gate-chain setup for Terraform/OpenTofu and Kubernetes (with GitLab CI and Jenkins variants), contract-first prompting templates for modules, manifests, and workflows, the pipeline-migration parity harness, CI-diagnosis prompt patterns per failure class, and the advisory-review rubric with client-safe redaction rules for services engagements. Do this at work this week → pb-08 Terraform Module Drafting with the Full Verification Chain (the gate chain, hands-on), pb-11 Kubernetes Manifests and Helm Charts with a Schema-Validation Loop (the kubeconform + kube-score loop), and pb-04 An Advisory AI Review Gate for Infra PRs (advisory, never blocking). Five labs anchor the module and run together in the guided journey's Build stage: the IaC verification pipeline with seeded AI errors (lab-01), the K8s validation loop (lab-02), the CI failure autopsy across five failure classes (lab-03), the Jenkins-to-Actions migration with parity harness (lab-04), and the advisory review bot scored for precision against known issues (lab-05). All five run at zero cost on OSS tooling and kind/minikube.

Further Reading

This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in