DevOps6 min read

Terraform Remote State on S3: A Safe Default

Why local Terraform state breaks teams, and the S3 + DynamoDB setup that fixes it without a paid backend.

DM

Deep Mehta

Founder & Cloud Engineer

Terraform's default is to keep state in a local terraform.tfstate file next to your code. That is fine for a solo experiment and a genuine problem the moment a second person runs terraform apply. The state drifts, applies collide, and eventually someone commits a state file to Git with a plaintext secret in it.

The fix is a remote backend. On AWS the boring, correct default is an S3 bucket for the state plus a DynamoDB table for locking.

Why local state breaks teams

State is Terraform's memory of what it built. Two people with two copies means two memories that disagree. There is no locking, so concurrent applies race each other. And a local file is one careless git add away from leaking.

  • No locking: concurrent applies corrupt state
  • No sharing: each machine has its own truth
  • No history: a bad apply is hard to roll back
  • Leak risk: state often contains secrets

The S3 + DynamoDB backend

S3 stores the state file; DynamoDB holds a lock so only one apply runs at a time. Turn on versioning and encryption on the bucket so every change is recoverable and nothing sits in plaintext.

text
terraform {
  backend "s3" {
    bucket         = "mycompany-tf-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "tf-locks"
    encrypt        = true
  }
}

Create the bucket and table once, out of band, before you migrate. Block all public access on the bucket, enable versioning, and enable default encryption.

Treat the state bucket like a credential store, because that is effectively what it is. Private, encrypted, versioned, no exceptions.

Migrating without downtime

Add the backend block, then run terraform init. Terraform detects the change and offers to copy your existing local state up to S3. Say yes, verify a terraform plan shows no changes, and delete the local file.

That is the whole trick. It is not clever and it does not need to be. If you want this wired into a CI pipeline with locking that survives failed jobs, that is part of what our CI/CD work sets up.

#Terraform#AWS#IaC
DM

About the author

Deep Mehta

Deep is the founder of 3 Dices Technology, a cloud engineering studio shipping AWS architecture, DevOps automation, and production AI systems for startups and SMBs.

Connect on LinkedIn

Frequently Asked Questions

Do I need DynamoDB for Terraform state locking?
For any team, yes. Without a lock table two applies can run at once and corrupt state. The table is tiny and costs cents.
Should state buckets be public?
Never. State files contain resource metadata and sometimes secrets. Block all public access and enable encryption and versioning.

Have a Question This Didn't Answer?

Ask us directly, we're happy to share what we know about your specific situation.