Lesson 08 of 14 · Modules
IaC generation & validation
Generate Terraform and Kubernetes manifests with AI, then prove them correct with a validation pipeline: formatting and validation, linting, security and policy checks, schema validation, plans reviewed by humans, and pinned versions that stop invented or outdated arguments.
Generate, then prove
AI is quick at producing Terraform modules, Helm values and Kubernetes manifests. It's also prone to invented arguments, outdated syntax and insecure defaults. The answer is a pipeline where generated code must pass the same (or stricter) gates as human code.
A robot can draw house plans very fast. Before building, the plans go to the building inspector (validate), the safety officer (security scan), and the town rules office (policy). Then the owner looks at the plan and says, "Yes, that's the house I want, in the right place."
Prompting for better IaC
Write a Terraform module for an S3 bucket for application logs.
Constraints: AWS provider ~> 5.0; block public access; SSE-KMS with a variable key ARN;
versioning on; lifecycle: transition to STANDARD_IA after 30 days, expire after 365;
separate aws_s3_bucket_* resources (not deprecated inline blocks); variables with
descriptions and validation; outputs for bucket ARN and name. Include a README with an example.
Stating the provider version and "separate resources, not deprecated inline blocks" steers away from outdated patterns (e.g. the AWS provider v4+ split of bucket sub-resources).
The Terraform gate
$ terraform fmt -check -recursive
$ terraform init -backend=false && terraform validate
$ tflint --recursive
$ checkov -d . --quiet # or: trivy config .
$ terraform plan -out tfplan && terraform show -json tfplan > plan.json
$ conftest test plan.json -p policy/
Example Rego policy (conftest) requiring encryption on buckets:
package main
deny[msg] {
rc := input.resource_changes[_]
rc.type == "aws_s3_bucket_server_side_encryption_configuration"
rule := rc.change.after.rule[_]
not rule.apply_server_side_encryption_by_default[_].sse_algorithm
msg := sprintf("%s: encryption algorithm must be set", [rc.address])
}
(Rego syntax differs between OPA versions, e.g. deny contains msg if { … } in newer Rego; use the style your conftest/OPA version expects.)
The Kubernetes gate
$ kubeconform -strict -summary -schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
rendered/
$ kube-linter lint rendered/
$ kubectl apply --dry-run=server -f rendered/ # against a test cluster with the CRDs
$ kyverno apply policies/ --resource rendered/
Human review of the plan
Automated gates confirm validity and policy. A human confirms intent: correct account/cluster, expected number of changes, no surprise replacements (-/+ in plans), acceptable blast radius, rollback path. (See Terraform & Infrastructure as Code, lesson 07 for production patterns.)
Try it: generate and gate
- Ask an assistant for the S3 logs module above (or an equivalent on your cloud/libvirt).
- Run the Terraform gate; record every failure and whether it came from AI output (invented argument, deprecated block, insecure default).
- Write one conftest policy and make it fail on purpose, then fix the module.
- Generate a Deployment + Service + HPA for a sample app; run the Kubernetes gate and fix findings.
- Put both gates into a CI workflow that runs on every PR.
Going deeper: IaC with AI at scale
- Provide golden modules and examples in the repo, and reference them in project memory (CLAUDE.md), so generated code reuses them instead of reinventing.
- Keep policies as code with tests (
opa test), versioned with the repos they protect. - Track which gate catches AI-generated issues most; strengthen earlier gates to fail fast.
Recap
- AI drafts IaC fast, with risks of invented/outdated arguments and insecure defaults.
- Terraform gate: fmt, validate, tflint, checkov/trivy, plan → conftest.
- Kubernetes gate: kubeconform, kube-linter, server-side dry run, policy engine.
- Pin versions; humans review the plan for intent.
This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.