patternbashterraformMajor
Remote state with S3 backend: correct bucket, key, and encryption configuration
Viewed 0 times
Requires AWS provider >= 4.0 for the separate versioning resource
s3 backendremote statestate encryptionversioningdynamodb lockbackend configuration
aws
Error Messages
Problem
Configuring an S3 backend incorrectly (wrong region, missing encryption, no versioning) leads to state corruption, loss, or security exposure. Common mistakes include hard-coding credentials in the backend block and forgetting to enable versioning for state recovery.
Solution
Configure the S3 backend with encryption, versioning, and a DynamoDB table for state locking. Never hard-code credentials in the backend block — use AWS environment variables or instance profiles.
Create the S3 bucket and DynamoDB table (bootstrap separately or with a dedicated Terraform workspace):
terraform {
backend "s3" {
bucket = "my-terraform-state-prod"
key = "services/api/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}Create the S3 bucket and DynamoDB table (bootstrap separately or with a dedicated Terraform workspace):
resource "aws_s3_bucket" "tfstate" {
bucket = "my-terraform-state-prod"
}
resource "aws_s3_bucket_versioning" "tfstate" {
bucket = aws_s3_bucket.tfstate.id
versioning_configuration { status = "Enabled" }
}
resource "aws_s3_bucket_server_side_encryption_configuration" "tfstate" {
bucket = aws_s3_bucket.tfstate.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
}
}
resource "aws_dynamodb_table" "tflock" {
name = "terraform-state-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}Why
S3 without versioning means a corrupted or deleted state file is unrecoverable. Without encryption, state content (including secrets) is readable to anyone with S3 access. Without the DynamoDB lock table, concurrent applies can corrupt state.
Gotchas
- The backend block does not support interpolation — bucket names must be literal strings
- Use
terraform init -backend-config=backend.hclwith a separate file for environment-specific backend config - The bootstrap S3 bucket and DynamoDB table cannot themselves be managed by the workspace that uses them
Context
Setting up shared Terraform state for team or CI/CD use on AWS
Revisions (0)
No revisions yet.