State Management
The memory your plans depend on
IaC state is the tool's memory and the source of a plan's 'reality'. Remote backends with locking, backup, and audit are non-negotiable in teams; misuse of state is the top reason infra tools bite.
What you will learn
- Explain why state is essential, not incidental
- Configure remote backends with locking + backup
- Handle state surgery: import, move, remove, migration
Every resource your tool owns has a state entry (attributes, IDs, dependencies). Remote state + locking avoid concurrent applies; backups save you from corruption. 'Where is state?' is the first question of any method review.
What is this?
Backend options: local (bad for teams), S3 (AWS; dynamodb lock), GCS (state bucket), Azure blob+Lease; Terraform Cloud remote; OpenTofu remote. Features: consistency (read-before-plane), locking (avoid two applies racing), state versioning (rollback), workspaces (parallel envs on one backend) vs state per directory. Surgical commands: terraform import (adopt existing infra), state mv/rm/pull/push/shallow list; Tainted resources (legacy) vs replace. Drift detection: refresh/plan compares state vs provider's view. Corruption/hand-edits/forks → reinit, recovery from backup, or manual import/reconstruct. Secrets in state (plan outputs, values): encrypt the backend, restrict read access.
Why do you need it?
- Without remote state, two engineers plan against stale snapshots → clobbering applies.
- Locking is the difference between 'worked earlier' and 'worked in parallel twice'.
- State unvblocked import/moves mean migrating manual infra to code without rebuild.
- A corrupted local state file destroyed more infra than any misconfig I've debugged.
Mental model
A construction logbook shared by all crews, updated and locked nightly
Remote state
Each crew (engineer) reads the logbook before laying anything (plan) and writes when done (apply); the on-night lock (dynamo lock) keeps two crews from pouring concrete over each other's work.
How it works
- Every apply writes each resource's final attributes into state.
- Next plan reads state + queries the provider for living resources.
- Locking (DynamoDB/consul/GCS object lock) holds during apply, released after.
- State versioned in the backend (S3 objects history) for rollback to prior versions.
- Import/move edit the address book so existing resources join the codebase's graph.
State as memory lane.
Examples
A healthy remote backend shape
terraform { backend "s3" { bucket = "acme-tfstate-prod" key = "checkout/terraform.tfstate" region = "us-east-1" dynamodb_table = "tf-locks" encrypt = true }}# now: two people run apply → only one wins the lockRemote, locked, encrypted, versioned: the gold-standard memory for any team touching the same infra.
In production
- Per-environment state files (or dirs) in one bucket, keyed by env.
- terraform import to adopt 200 dusty resources from console clicks.
- State rollback via backend object version when a bad apply sweeps a resource.
Best practices
- Remote + locked backend for every team; local state only for throwaway demos.
- Keep state read permission narrow; treat it as secrets (encrypt).
- Never hand-edit state; use the tool's surgery commands or a careful recovery.
- Add drift checks: scheduled plan+diff alerts when state reality diverges from code.
- Document the backend + who owns it in every repo's README.
Common mistakes
- Storing state in git (the .tfstate-in-repo legendary footgun).
- No lock table → two applies race and both think they won.
- Import without a post-import plan review → surprise force-new cascades.
- state rm used as a dirty delete → real resources orphaned and now untracked.
Debugging tips
- Plan shows delete+create of something stable → check for a state identity mismatch (ids/ARN).
- Out-of-band change made in console but plan shows nothing → state/permissions hide it; refresh to see reality.
- Concurrent apply errors → inspect the lock table's LeaseID entry and break stale leases cautiously.
- State read blocked → IAM/bucket policy; verify the exact backend key exists.
Interview checkpoint
Hands-on lab
- Configure a remote backend with locking
- Simulate concurrent applies and watch the lock work
- Recover/rollback from a versioned state
Share and Lock State Across Two Runs
40 min · advanced
Quick quiz
Two engineers running apply on a shared remote backend without locking:
Adopting a hand-created resource into code's graph uses: