How to Configure S3 and DynamoDB Remote State in CI
An S3 backend keeps state off the runner, and a DynamoDB lock table serializes runs so two apply jobs cannot write state at once.
Declare an S3 backend block with a DynamoDB dynamodb_table for locking. Authenticate via OIDC and run terraform init to bind the backend in CI.
backend block
main.tf
terraform {
backend "s3" {
bucket = "acme-tf-state"
key = "prod/app/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "acme-tf-locks"
encrypt = true
}
}Init in CI
.github/workflows/ci.yml
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::111122223333:role/tf-ci
aws-region: us-east-1
- run: terraform init -input=falseGotchas
- The DynamoDB table needs a primary key named
LockID(string) or locking fails. - Grant the CI role s3:GetObject/PutObject on the state key plus dynamodb:PutItem/DeleteItem on the lock table.
Related guides
How to Authenticate Terraform to AWS With OIDC in CIAuthenticate Terraform to AWS from GitHub Actions using OIDC and a short-lived assumed role, removing long-li…
How to Handle a Stale Terraform State Lock in CIRecover from a stuck Terraform state lock left by a killed CI job by reading the lock ID from the error and r…