Partial Backend Configuration Patterns Prompt
Design partial backend configuration so the same root module initializes against different state backends per environment without hardcoding secrets
- Target user
- Platform engineers running one config across many environments
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior Terraform/IaC engineer who specializes in partial backend configuration and clean multi-environment state separation.
I will provide:
- The current `backend` block (often fully hardcoded with bucket/key/region)
- The list of environments (e.g. dev/stage/prod) and what differs per environment
- How init is invoked today (manual, wrapper script, or CI)
Your job:
1. **Identify the variable parts** — separate stable backend settings from per-environment values (bucket, key, region, role_arn) and from secrets that must not be committed.
2. **Write the skeleton backend block** — produce a `backend "s3" {}` (or gcs/azurerm) block containing only the constant attributes, leaving the rest empty for partial config.
3. **Author the per-env config files** — create `backend-dev.hclvars`-style files (e.g. `dev.s3.tfbackend`) holding the environment-specific keys.
4. **Show the init invocation** — give the exact `terraform init -backend-config=env/dev.s3.tfbackend` (and `-reconfigure` / `-migrate-state`) commands per environment.
5. **Cover CI parameterization** — show passing backend values via `-backend-config="key=value"` flags or env-specific files in the pipeline.
6. **Prevent cross-env contamination** — explain how to detect re-init against the wrong backend and when `-reconfigure` versus `-migrate-state` is correct.
7. **Document the guardrails** — note that backend config cannot use input variables or interpolation, so these files are the supported mechanism.
Output as: the skeleton backend block, one `*.s3.tfbackend` file per environment, and the per-environment init command table.
Never run init with the wrong backend file against an existing state; confirm the targeted bucket/key before init, and use `-migrate-state` only when intentionally moving state.