Preventing State Corruption: Implementing Terraform State Locking
Learn how Terraform state locking prevents concurrent modifications, how to set it up with AWS S3 and DynamoDB, and when to safely use force-unlock.
28 Jul 2025, 14:12 UTC

The Risk of Concurrent Applies
When working in a team, the biggest risk to your infrastructure isn't a bad configuration—it's two people applying different changes to the same state file at the same time. Terraform uses a state file to map your code to real-world resources. If two processes attempt to write to this file simultaneously, you risk state corruption, where the file becomes unreadable or represents a hybrid of two different infrastructure versions.
How State Locking Works
State locking is not a feature of the Terraform binary itself; it is provided by the backend that stores the state file. Local state files (terraform.tfstate) have no locking mechanism, making them unsuitable for collaboration.
- HashiCorp Cloud/Terraform Cloud: Locking is handled natively.
- Azure Blob Storage: Uses native lease capabilities.
- AWS S3: Requires a separate DynamoDB table to track the lock ID.
Worked Example: S3 and DynamoDB Configuration
To enable locking on AWS, create an S3 bucket for the state file and a DynamoDB table with a partition key named LockID (String). Then configure the backend:
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-lock"
encrypt = true
}
}
Verification steps:
- Run
terraform initto migrate state to the S3 bucket. - Open two terminal windows.
- In the first window, execute
terraform applyand leave it waiting for confirmation. - In the second window, run
terraform apply.
The second terminal will fail with an error like Error: Error acquiring the state lock and display a Lock Info ID.
Handling Stuck Locks
If a process crashes before releasing the lock, the lock record remains in DynamoDB, blocking further operations. You can manually release it with the force-unlock command, using the Lock ID from the error:
terraform force-unlock <LOCK_ID>
Warning: Only run force-unlock when you are certain no other Terraform process is active. Forcing a unlock while an apply is running can corrupt the state.
Limitations and Trade‑offs
- Permission overhead: IAM policies must allow
s3:GetObject,s3:PutObjecton the bucket anddynamodb:GetItem,dynamodb:PutItem,dynamodb:DeleteItemon the lock table. - Sequential bottleneck: Locking serializes changes; large teams may need to split infrastructure into smaller state files using separate directories or workspaces.
Final Checklist
- Is the state stored in a remote backend? (Local state = no locking.)
- If using S3, does the DynamoDB table have the exact partition key
LockID? - Do all users and CI/CD service accounts have read/write access to both the S3 bucket and the DynamoDB lock table?
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.