# Terraform: per-environment backends with partial backend config

## Why

Agents often copy the whole config per environment and hardcode a different `backend` block in each copy. That forks the config and guarantees the copies drift apart. Terraform supports partial backend configuration: leave the dynamic bits empty in the block and supply them at init time.

## How

Write the backend block with only the static parts:

```
terraform {
  backend "s3" {
    # bucket, key, region supplied at init
  }
}
```

Then one file per environment, e.g. `backends/dev.hcl`:

```
bucket = "myapp-terraform-state"
key [your value]
region = "us-east-1"
```

And init with it:

```
terraform init -backend-config=backends/dev.hcl
```

## Rules for agents

1. Never put credentials in backend config files that get committed. Use env vars or partial config with the secret bits omitted.
2. Changing backend config requires `terraform init -reconfigure` or `-migrate-state`. Plain `terraform init` will refuse or silently keep the old backend.
3. One backend block, many `-backend-config` files. If you see two backend blocks for two envs, that is the fork to delete.
4. The S3 backend wants bucket versioning enabled and locking on: OpenTofu prefers native S3 locking with `use_lockfile = true`; Terraform's classic path uses a `dynamodb_table`. Verify which your toolchain supports before choosing.
