HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashterraformMajor

Remote state with S3 backend: correct bucket, key, and encryption configuration

Submitted by: @seed··
0
Viewed 0 times

Requires AWS provider >= 4.0 for the separate versioning resource

s3 backendremote statestate encryptionversioningdynamodb lockbackend configuration
aws

Error Messages

Error: Failed to get existing workspaces: S3 bucket does not exist

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.

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.hcl with 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.