Shared state and locking
🎯You'll be able to
Store state where the whole team and the pipeline can use it, with locking so two applies can't run at once, and protect it properly.
🏠The everyday picture
A shared train reservation chart has one copy, at the station. When a clerk books a seat, they hold the chart until they've written the name, so two clerks can't sell the same seat. If each clerk kept their own chart, double bookings would follow.
📘What it really is
-
With local state (the default),
terraform.tfstatelives on one computer. A colleague applying from their laptop has a different state, and Terraform may try to create everything again or undo the other person's changes. -
A remote backend stores state in a shared place:
hcl terraform { backend "s3" { bucket = "routerani-tf-state" key = "prod/terraform.tfstate" region = "ap-south-1" encrypt = true use_lockfile = true } }Others include Google Cloud Storage (gcs), Azure Storage (azurerm) and HCP Terraform (HashiCorp's hosted service). -
Locking: while one
planorapplyruns, the backend holds a lock; a second one waits or stops withError acquiring the state lock. - The local backend locks too, but only on one computer.
- On S3, Terraform 1.11 and later can lock with a lock file in the bucket (
use_lockfile = true); older setups used a DynamoDB table. -
terraform force-unlock <ID>removes a stale lock left by a crashed run. Check first that nobody is really applying. -
Protecting state (it holds secrets, CD3 Lesson 3):
- encryption at rest and in transit;
- access only for the people and pipelines that run Terraform;
- versioning on the bucket, so a corrupted or wrongly overwritten state can be restored;
-
no public access, ever.
-
The bootstrap problem: the bucket holding state must exist before Terraform can use it. Teams create it once with a small separate configuration (with local state) or by hand, and document it.
📝A worked example
Input: in the RouteRani kit, run terraform apply -var app_count=3 in one terminal and, while it runs, terraform plan in a second terminal
in the same folder.
Expected output: the second command stops with Error acquiring the state lock and shows who holds the lock and since when (the local
backend's lock is the file .terraform.tfstate.lock.info). Once the apply finishes, the plan runs. A remote backend does the same thing for
everyone on the team and the pipeline.
🌍Where it's used
- Every team using Terraform beyond one person.
- CI pipelines that apply automatically (Lesson 4) need the same state as the engineers.
- Audits: bucket versioning and access logs show every state change.
📝Case scenario
Two engineers at a payments startup applied changes to the same environment within a minute of each other, each from local state on their laptop. The second apply didn't know about the first engineer's new firewall rule and removed it, cutting off a partner bank's connection for an hour. Moving state to an encrypted bucket with locking made the second apply wait.
🖱️Try it
Run the two-terminal example above. Then look at .terraform.tfstate.lock.info while the apply runs (cat infra/.terraform.tfstate.lock.info).
Success: you've seen the lock, its ID and who holds it, and the second command waiting.
⚠️Common mistakes
- State on laptops. Sign: "it works from my machine" applies and surprise deletions. Fix: a remote backend with locking.
- Force-unlocking a live run. Sign: two applies interleaving and a confused state. Fix: confirm the holder has stopped before
force-unlock. - An unprotected state bucket. Sign: wide read access or no versioning. Fix: encryption, least-privilege access, versioning, no public access.
🛠️For your project
The projects use local state on your computer. In your capstone write-up, explain which backend you would use for RouteRani in a team and why.
✅Quick check
What does state locking prevent?
Show the answer
Two plans or applies changing the same state at the same time.
Why turn on versioning for the state bucket?
Show the answer
To restore an earlier state if it's corrupted or overwritten.
