The design is approved; now it must become Terraform someone can actually build on. AI drafts the module skeletons as the design-to-build handoff artifact — and nothing ships until the draft survives the validate→plan→policy→cost chain, because LLMs hallucinate resource types and attributes with total confidence.
Tier: Core · Hands-on time: ~30 minutes
Research on LLM-generated Terraform is blunt: models invent HCL resource types, misname attributes, and misremember provider schemas — code that looks idiomatic and fails terraform validate, or worse, validates and provisions something subtly different from the design. The architect's job here is not to write the modules (the platform team owns the build) but to hand over a skeleton that encodes the design's decisions — boundaries, naming, non-negotiable settings — with the failure modes already caught. The deterministic gate chain, not the architect's eyeball, is what decides the skeleton is sound.
Skip AI when your platform team has a module registry that covers the design — composing existing blessed modules by hand beats generating fresh code they will have to review harder.
terraform validate and terraform plan against a sandbox account; a policy scanner (Checkov-class); a cost estimator (Infracost-class). Category 05 owns operating this chain in CI; the architect must still run it before handoff.Extract the design's invariants first. Before generating, list what the code must encode because the design says so: network boundaries, encryption settings, region pinning, naming/tagging standards, the deny-by-default posture. These are the skeleton's reason to exist — a skeleton without invariants is scaffolding anyone could have generated.
Generate module by module, not stack at once.
Generate a Terraform module skeleton for the retrieval tier of
orbit-docs-copilot, following the conventions in modules/example-service/.
Design invariants (must be encoded, not commented):
- All data resources in eu-central-1 only; no cross-region replication.
- Postgres (with pgvector) reachable only from the app subnet; no
public accessibility anywhere.
- Encryption at rest with a customer-managed key passed in as a
variable; encryption settings must not be defaulted.
- Mandatory tags: service, env, data-classification, cost-center —
as required variables, not literals.
Rules:
- Variables with types and descriptions; outputs for everything a
consuming module needs; no hardcoded environment values.
- Where you are not certain an attribute name is correct for the
provider version, add a comment "# CHECK-DOCS" on that line
rather than guessing silently.
- Skeleton depth: resources, wiring, and invariants — not every
optional attribute. The platform team owns completion.
Run the chain, in order, and fix in conversation. terraform validate catches invented resource types and attribute names — expect it to catch some; that is the chain doing its job, not a reason to distrust the whole draft. Then terraform plan against the sandbox: read the plan output resource by resource — this is where "validates but provisions the wrong thing" surfaces (a publicly accessible database that validated fine). Paste errors back with scope: "fix only the failing attribute, change nothing else."
Gate for policy, then cost. Checkov-class scanning catches the security defaults models love (open egress, unencrypted state, wildcard IAM). Infracost turns the plan into money — AI-drafted skeletons habitually over-provision (three NAT gateways where the design implies one, oversized instances "for safety"). Every policy finding is either fixed or documented as a deliberate exception; every cost line is sanity-checked against the design's cost model.
Audit the invariants by hand. The chain proves the code is valid, compliant, and priced — not that it encodes your design. Walk the invariant list from step 1 against the final code: is region pinning enforced or defaulted? Could a consumer override the encryption key requirement? Is the database's network path actually restricted to the app subnet? This ten-minute read is the architect's signature on the handoff.
Hand off with provenance. PR the skeleton with: the design links (HLD, ADRs), the chain results (validate/plan/policy/cost outputs), the CHECK-DOCS resolutions, and an explicit "skeleton, not production" label. The platform team receives a starting point whose failure modes are pre-caught and whose decisions are traceable — the handoff artifact the design phase owes the build phase.
Skeletons for client estates encode client network topology and naming — MSA-governed material. Generate inside the boundary: Claude Code against the client-tenancy endpoint, or a local coding model via Ollama (HCL generation degrades gracefully on smaller models when the prompt carries a style example). The gate chain is fully offline-capable — validate, plan against the client's sandbox account, Checkov and Infracost run locally — so the verification story is identical in every environment. Never run terraform plan for a client stack from outside their approved credential path; the chain runs where the client's credentials legitimately live.
The skeleton's value is the invariants it encodes and the chain it survived. AI writes HCL fast; validate→plan→policy→cost decides whether it is infrastructure or fiction.