State Locking
Locking stops two applies from running at once and corrupting the shared state file.
terraform force-unlock LOCK_IDState locking ensures that only one Terraform operation writes to the state at a time. Without it, two simultaneous applies could overwrite each other and leave state inconsistent.
How it works with S3 + DynamoDB
Before writing, Terraform puts a lock record in the DynamoDB table. Anyone else who tries to apply sees the lock and waits. When the operation finishes, the lock is released.
If a lock gets stuck
A crashed run can leave a lock behind. As a last resort, terraform force-unlock with the lock ID removes it — only when you are sure no run is active.
Example
# A locked state produces an error like this:
# Error: Error acquiring the state lock
# Lock Info:
# ID: 9db590f1-9e2c-...
# Who: alice@soundscode
# Once you are certain nothing is running, remove it:
terraform force-unlock 9db590f1-9e2c-4e3a-b1c2-abcdef123456When to use it
- Two CI pipelines trigger at the same time, but DynamoDB locking ensures only one apply proceeds while the other waits, preventing state corruption.
- A developer tries to run terraform apply while a colleague's apply is in progress and receives a 'state is locked' error with the lock holder's ID, so they wait.
- An operator uses terraform force-unlock with the lock ID to release a stale lock left behind by a CI pipeline that was killed mid-apply.
More examples
DynamoDB lock table creation
Creates the DynamoDB table that the S3 backend uses for state locking, requiring only a single LockID string attribute.
resource "aws_dynamodb_table" "tf_lock" {
name = "terraform-state-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}S3 backend with locking enabled
References the DynamoDB table in the S3 backend configuration to activate automatic state locking on every operation.
terraform {
backend "s3" {
bucket = "my-org-terraform-state"
key = "prod/app.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock" # enables locking
}
}Release a stale lock
Shows how to identify a stale lock from the error output and release it with force-unlock using the displayed lock ID.
# See the lock error message
terraform apply
# Error: Error acquiring the state lock
# Lock Info:
# ID: 12345678-abcd-1234-efgh-000000000000
# ...CI pipeline killed mid-apply...
# Force-unlock using the ID from the error
terraform force-unlock 12345678-abcd-1234-efgh-000000000000
Discussion