3.6 KiB
3) Remote State with S3 + DynamoDB Lock (25 min)
By default, Terraform stores its state in a local file called terraform.tfstate.
This works fine for single-user setups, but in a team environment it can cause conflicts (two people updating at once).
To solve this, we move the state file to a remote backend (Amazon S3) and use DynamoDB for state locking.
This ensures only one person can apply changes at a time.
Step A: Create an S3 bucket for remote state
aws s3api create-bucket --bucket my-terraform-state-lab --region ap-south-1
- Creates a new S3 bucket called
my-terraform-state-lab. - The bucket name must be globally unique across AWS. Change it to something like
terraform-state-yourname123.
aws s3api put-bucket-versioning --bucket my-terraform-state-lab --versioning-configuration Status=Enabled
- Enables versioning on the bucket.
- This allows you to roll back to older state files if something goes wrong.
Step B: Create a DynamoDB table for state locking
aws dynamodb create-table --table-name terraform-locks --attribute-definitions AttributeName=LockID,AttributeType=S --key-schema AttributeName=LockID,KeyType=HASH --billing-mode PAY_PER_REQUEST
- Creates a DynamoDB table called
terraform-locks. - The
LockIDcolumn acts as a lock key. - When Terraform runs, it inserts a lock entry in this table. This prevents two users from applying changes at the same time.
Step C: Configure backend in Terraform
Create a new project folder and move into it:
mkdir -p ~/terraform-remote-lab && cd ~/terraform-remote-lab
Now create a file called main.tf:
terraform {
backend "s3" {
bucket = "my-terraform-state-lab" # replace with your bucket name
key = "dev/terraform.tfstate" # file path inside the bucket
region = "ap-south-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
provider "aws" {
region = "ap-south-1"
}
resource "aws_s3_bucket" "demo" {
bucket = "my-demo-bucket-student12345" # must be unique
acl = "private"
}
Explanation of the configuration
-
backend "s3" → Tells Terraform to store state in S3.
bucket: Your S3 bucket name.key: Path/name of the state file inside the bucket.region: Region of your bucket.dynamodb_table: Table used for locks.encrypt: Ensures the state file is encrypted at rest.
-
provider "aws" → Tells Terraform to use AWS as the provider.
-
resource "aws_s3_bucket" "demo" → A sample resource (an S3 bucket) to test remote state functionality.
Step D: Initialize the backend
terraform init
- Initializes the working directory.
- Terraform will detect the
backend "s3"block and migrate your local state to S3. - You may be asked: Do you want to copy existing state to the new backend? → type
yes.
Step E: Apply and verify
terraform apply -auto-approve
- Creates the demo bucket defined in
main.tf. - Stores the state file in S3 instead of locally.
- Uses DynamoDB to prevent parallel execution.
Now check in AWS Console:
- Go to S3 → your bucket → dev/terraform.tfstate → you should see the state file.
- Go to DynamoDB → terraform-locks → while Terraform runs, a lock record will appear.
Wrap-Up
You have now:
- Configured Terraform to use a remote state in S3.
- Added versioning for rollback.
- Used DynamoDB locking for safe team collaboration.
This setup is considered a best practice for production environments.