🏔️ Reading Terraform Error Output
4 exercises — read real terraform plan/apply error output. State locks, forced replacements, dependency cycles, and "already exists" errors.
Terraform plan symbols
+create ·-destroy ·~update in place ·-/+destroy then recreate# forces replacement— the provider comment explaining why an in-place update isn't possible- "Error acquiring the state lock" — a safety mechanism, not a crash; someone else is applying right now
- "Cycle: ..." — a circular dependency in your resource graph, most often in security group rules
Talking about it out loud (Slack / stand-up)
- "Apply's blocked — state lock's held by another CI run, checking if it's still going."
- "Heads up, this plan replaces the instance, not updates it — might mean downtime."
- "Terraform found a circular dependency between the security groups — restructuring the rules."
- "The bucket already exists in our account, state just doesn't know about it — I'll import it."
0 / 4 completed
1 / 4
terraform apply output — state lock error
{ex.passage} What does "Error acquiring the state lock" mean, and what does the "Who: ci@runner-3421" line tell you?
State locking prevents two applies from writing to the same state file at once — this is a safety mechanism, not a crash.
Terraform state (
The
What NOT to do: don't reach for
The correct approach: wait for the other run to finish, or if it's confirmed stuck/dead, use
How to describe this to a colleague: "Apply is blocked — state lock is held by another CI run, ID starts with 4f9b2e1a. Let me check if that run is still going before I force-unlock anything."
Terraform state (
terraform.tfstate) is the single source of truth mapping your configuration to real infrastructure. If two terraform apply runs happened simultaneously against the same state, they could corrupt it or apply conflicting changes. To prevent this, Terraform acquires a lock (often backed by a DynamoDB table when using an S3 remote backend) before making changes.The
Lock Info block tells you exactly who is holding the lock right now: Who: ci@runner-3421 means a CI pipeline run currently has it — most likely another pipeline run is still in progress, or a previous run crashed without releasing the lock.What NOT to do: don't reach for
-lock=false as a first response — that disables the safety check entirely and risks real state corruption if the other process is genuinely still running.The correct approach: wait for the other run to finish, or if it's confirmed stuck/dead, use
terraform force-unlock <LOCK_ID> with the ID shown (here 4f9b2e1a-...) after confirming with the team that no other apply is actually in progress.How to describe this to a colleague: "Apply is blocked — state lock is held by another CI run, ID starts with 4f9b2e1a. Let me check if that run is still going before I force-unlock anything."