Terraform / IaC
Pathrule2 Rules • 2 Memories • 1 Skill
A guardrail bundle for teams managing infrastructure as code with Terraform 1.11+ on AWS. It enforces remote state with native S3 locking, pinned providers and modules, secrets kept out of state via write-only arguments, and a CI pipeline that always reviews a plan before apply. Built so AI agents make the same safe choices a senior platform engineer would.
Suggested path map
Pathrule places each piece on the matching path, so your assistant only sees it where it belongs. This is the scoping you get on import; you can adjust it in your workspace.
Rules
2Remote state with native locking only/infraEvery root module uses an encrypted, versioned S3 backend with use_lockfile.
| 1 | State lives in a remote backend with locking, encryption, and versioning. Never local, never unlocked. |
| 2 | |
| 3 | - Configure the `s3` backend with `use_lockfile = true` (GA since Terraform 1.11); do not add a `dynamodb_table` lock, that path is deprecated. |
| 4 | - Enable bucket versioning and SSE-KMS (`encrypt = true` plus a customer-managed `kms_key_id`) so state is recoverable and encrypted at rest. |
| 5 | - Give each environment its own state `key` and isolated IAM access; never share one state file across `dev`, `staging`, and `prod`. |
| 6 | - Never commit `terraform.tfstate` or `*.tfstate.backup`; treat state as a secret and keep it out of git. |
Plan-gated, OIDC-authenticated CI/.github/workflowshighstrictCI authenticates via OIDC and applies only a reviewed plan artifact.
| 1 | The pipeline runs `terraform plan`, saves it as an artifact, and applies that exact plan after approval. |
| 2 | |
| 3 | - Use `terraform plan -out=tfplan` then `terraform apply tfplan`; never re-plan at apply time, the applied change must match what was reviewed. |
| 4 | - Authenticate to the cloud with short-lived OIDC tokens (GitHub Actions `id-token: write`), never long-lived static access keys in secrets. |
| 5 | - Scope the apply role to least privilege, and prefer a read-only identity for `plan` and a separate write identity for `apply`. |
| 6 | - Gate `apply` on a manual approval or protected environment so a human signs off on the plan before infrastructure changes. |
Memories
2Module and provider versioning conventions/infra/modulesHow we pin, structure, and version reusable modules and providers.
| 1 | Reusable infrastructure is composed from versioned modules with pinned providers. |
| 2 | |
| 3 | - Pin every provider in `required_providers` with `~>` constraints and commit `.terraform.lock.hcl` so every run and teammate resolves identical versions. |
| 4 | - Set `required_version` to the supported Terraform line (1.15.x as of mid-2026; 1.13 is EOL); bump deliberately, not implicitly. |
| 5 | - Source registry and git modules with an explicit `version` or pinned `?ref=` tag, never a floating `main` branch. |
| 6 | - Keep modules small and single-purpose with typed `variables.tf`, `outputs.tf`, and a README; root modules in `/infra/environments` only wire modules together. |
Secrets and tagging conventions/infraKeep secrets out of state and tag every resource consistently.
| 1 | Sensitive values never land in state, and every resource carries a consistent tag set. |
| 2 | |
| 3 | - Use write-only arguments (e.g. `password_wo` with `password_wo_version`) and `ephemeral` resources/values (Terraform 1.11+) for passwords and tokens so they never persist to state or plan files. |
| 4 | - Source secrets at apply time from a secrets manager (AWS Secrets Manager / SSM Parameter Store) data sources; do not hardcode them in `*.tfvars` or commit them. |
| 5 | - Apply a baseline tag set via the AWS provider `default_tags` block: `Environment`, `Owner`, `ManagedBy = "terraform"`, and `CostCenter`. |
| 6 | - Mark sensitive outputs and variables `sensitive = true`, and remember that flag hides values from logs but does not encrypt or remove them from state. |
Skills
1terraform-iac-review/rootPre-merge checklist for any Terraform change.
| 1 | --- |
| 2 | name: terraform-iac-review |
| 3 | description: Pre-merge review checklist for Terraform / IaC changes covering remote state, locking, versioning, secrets, tagging, and plan-gated CI. Use before merging any Terraform PR. |
| 4 | --- |
| 5 | |
| 6 | # Terraform / IaC review |
| 7 | |
| 8 | - [ ] Remote `s3` backend configured with `use_lockfile = true`, no deprecated DynamoDB lock |
| 9 | - [ ] State bucket has versioning enabled and SSE-KMS encryption (`encrypt = true` + `kms_key_id`) |
| 10 | - [ ] Each environment uses an isolated state `key`; no state files committed to git |
| 11 | - [ ] `required_version` and all `required_providers` are pinned; `.terraform.lock.hcl` is committed |
| 12 | - [ ] Modules sourced with an explicit `version` or pinned `?ref=`, never a floating branch |
| 13 | - [ ] No secrets in `*.tfvars`, code, or state; write-only / ephemeral args used for passwords and tokens |
| 14 | - [ ] Sensitive variables and outputs marked `sensitive = true` |
| 15 | - [ ] `default_tags` applies the baseline tag set (`Environment`, `Owner`, `ManagedBy`, `CostCenter`) |
| 16 | - [ ] CI runs `terraform plan -out=tfplan` and applies that exact artifact after approval |
| 17 | - [ ] Cloud auth uses short-lived OIDC tokens with a least-privilege role, no static keys |
| 18 | - [ ] `terraform validate` and `terraform fmt -check` pass; a security scan (tfsec/Checkov/Trivy) is clean |
Why this pattern
AI agents and rushed PRs ship Terraform with unlocked state, drifting versions, secrets baked into state, and applies that never matched a reviewed plan.
Built for Platform, DevOps, and SRE teams running Terraform 1.11+ against AWS.
Keeps your assistant from:
- Concurrent applies corrupting unlocked remote state
- Secrets and tokens persisted in plaintext inside the state file
- Applying changes in CI that were never reviewed as a plan
- License
- Apache-2.0
- Version
- 1.0.0
- Updated
- 2026-06-09