Back to Blog
DevOps
Dec 12, 20252 min read

Terraform State Management: Kill Local State

Why committing .tfstate to Git is a security disaster. A guide to setting up robust S3+DynamoDB remote backends with encryption and locking.

Terraform State Management: Kill Local State
Share:

Author: CloudOpsPro Engineering Team
Category: DevOps, IaC, Security
Date: December 12, 2025

We still see it in 2025: A terraform.tfstate file committed to a Git repository. This is the DevOps equivalent of storing your credit card number on a sticky note in a public park.

Terraform State is the "brain" of your infrastructure. If it is lost, corrupted, or exposed, it is Game Over.


1. Why Git Storage is Fatal

  1. Secrets in Plain Text: Terraform state files store the results of resources. If you create an RDS database and pass a password, that password is stored in plain text in the state file. Commit to Git -> Secrets are compromised forever.

  2. No Locking: Two engineers run terraform apply at the same time. Git doesn't prevent this. They overwrite each other's changes. Result: Corrupted infrastructure and undefined state.

  3. Manual Errors: "Oops, I forgot to pull before applying." Now your local state is out of sync with reality.


2. The Solution: Remote Backends with Locking

The extensive standard is S3 + DynamoDB (on AWS).

  • S3 Bucket: Stores the state file (Versioning enabled).
  • DynamoDB Table: Handles the Locking.

Configuration Example

hcl
# backend.tf

terraform {
  backend "s3" {
    bucket         = "company-terraform-state-prod"
    key            = "vpc/terraform.tfstate"
    region         = "us-east-1"

    # The Lock Table
    dynamodb_table = "terraform-lock-table"

    # Encryption works by default, but explicit is better
    encrypt        = true
  }
}

Now, when Engineer A runs terraform plan, Terraform writes a Lock ID to DynamoDB. If Engineer B tries to run apply, Terraform checks DynamoDB, sees the lock, and errors out: Error: Error acquiring the state lock.

Safety secured.


3. Best Practices for State Security

Since the state file contains secrets (RDS passwords, IAM keys, TLS private keys):

  1. Encryption at Rest: Ensure the S3 bucket has Server-Side Encryption (SSE-S3 or KMS) enabled.
  2. Access Control: Only the CI/CD role and top-level admins should have s3:GetObject on the state bucket. Developers generally don't need raw state access; they just need to see the Plan output.
  3. Versioning: Enable S3 Versioning. If a terraform apply corrupts your state file, you can roll back the S3 object to the previous version to recover.

4. Terraform Cloud / Spacelift

If managing S3 backends feels too manual, managed backends like Terraform Cloud or Spacelift are excellent alternatives. They handle:

  • State hosting
  • Locking
  • History/Diffs of state
  • Run triggers

Verdict:

  • Small/Mid Teams: S3 + DynamoDB is fine (and free/cheap).
  • Large Enterprise: Use a managed backend for Audit logs and RBAC.

Whatever you do, add *.tfstate to your .gitignore right now.

Tagged with

TerraformSecurityDevOps

Need help with your infrastructure?

Book a free architecture review and get expert recommendations.

Book Architecture Review
Share:
CL
CloudOpsPro Team

Cloud Infrastructure & DevOps

Dec 12, 20252 min read

Read Next