How to configure Terraform remote state with locking
Store Terraform state in a remote S3 backend with DynamoDB locking so a team can collaborate without corrupting state. Covers setup, locking, and migration.
What and why
Terraform records what it manages in a state file. Local state cannot be shared safely: two people running apply at once can corrupt it. A remote backend stores state centrally and locks it during operations, so a team collaborates without conflicts.
Prerequisites
- Working Terraform configuration with local state.
- Permission to create the backend storage (an S3 bucket here).
- Terraform installed.
Steps
1. Create the backend storage
Provision a bucket to hold state and a DynamoDB table for locks. Create these once, outside the configuration that will use them, to avoid a chicken-and-egg problem.
2. Add the backend block
In terraform settings:
terraform {
backend "s3" {
bucket = "acme-tfstate"
key = "prod/network.tfstate"
region = "us-east-1"
}
}
The key is the path within the bucket and must be unique per state.
3. Enable state locking
Add a lock table so only one operation mutates state at a time:
backend "s3" {
bucket = "acme-tfstate"
key = "prod/network.tfstate"
region = "us-east-1"
dynamodb_table = "tf-locks"
}
Terraform acquires a lock during plan and apply and releases it when done.
4. Migrate existing state
terraform init -migrate-state
Terraform detects the new backend and offers to copy your local state into it. Confirm to migrate.
5. Test concurrent runs
Start terraform apply in one terminal, then start another apply while the first holds the lock. The second should report that state is locked and refuse to proceed, proving locking works.
Verification
Check the backend bucket for the state object at your key. Run terraform state list; it now reads from the remote backend. Delete the local terraform.tfstate file safely once migration is confirmed.
Next Steps
Use separate state keys or workspaces per environment. Enable bucket versioning so you can recover from a bad apply. Restrict backend access with least-privilege IAM so only CI and operators can touch state.
Prerequisites
- Working Terraform configuration
- An S3 bucket or equivalent backend
- Terraform installed
Steps
- 1Create the backend storage
- 2Add the backend block
- 3Enable state locking
- 4Migrate existing state
- 5Test concurrent runs
- 6Verify remote state