Terraform Style

Terraform can create, replace, or delete real infrastructure. Keep plans predictable and blast radius small.

Source baseline: docs/src/style/terraform.mdx. Source: docs/src/style/terraform.mdx

Defaults

Every root module: remote backend, locking enabled, explicit Terraform and provider versions, saved plan reviewed before apply, default tags on all resources.

State Boundaries

Split state by ownership and failure domain: networking, IAM, service stacks, data stacks. One key per service and environment. No monolithic state files. A single change should not require planning unrelated infrastructure.

Layout

iac/
├── modules/    # Reusable units
├── stacks/     # Deployable root modules
└── tfvars/     # Env-specific inputs and backend config

Variables and Data Sources

No hardcoded mutable identifiers (AMI IDs, subnet IDs, VPC IDs). Use variables for configuration and data sources for discovery. Hardcoded values acceptable for stable contracts like AWS managed policy ARNs.

Plan and Apply

Always use saved plans: terraform plan -out=tfplan, then terraform apply -input=false tfplan. Review plan output before apply. Apply production from CI/CD only. Require approval gates on protected environments. No -auto-approve when applying a saved tfplan.

Version Pinning

Set Terraform and provider constraints in every root. Commit .terraform.lock.hcl for CI/CD roots.

Tagging

Provider-level default tags: Environment, ManagedBy, Project, Owner. Add resource-specific tags as needed.

Multi-Cloud

Default rule: one state per cloud. Keep AWS, GCP, and Azure in separate stacks unless resources need atomic cross-cloud changes.

Infrastructure Contract

Concern Default Banned pattern Proof
State Split by ownership and failure domain One monolithic state for unrelated resources Plan touches only intended stack
Apply Saved plan reviewed before apply Direct production apply or -auto-approve Stored tfplan plus approval trace
Versions Terraform and provider constraints in every root Floating provider behavior Lockfile and init/validate
Inputs Variables/data sources for mutable identifiers Hardcoded mutable AMI/subnet/VPC ids Plan review
Tags Provider defaults plus resource-specific tags Untagged managed resources Plan or policy check

Proof

Terraform proof is the reviewed plan, not the config diff. A style-compliant change shows which stack owns the resources, what the plan will create/update/delete, and why the blast radius is limited to the intended failure domain.

Style Rule Contract

This page follows Style Rule Contract: name the default pattern, banned pattern, reason, exception, proof, and codification path clearly enough that the next agent can apply the rule without asking Kevin again. If a local repo has a stricter rule, follow the local rule and update the wiki when the decision becomes durable.


Timeline