Skip to main content

Command Palette

Search for a command to run...

Day 20: Remote State & Backend Configuration

Updated
6 min read
Day 20: Remote State & Backend Configuration
S

I'm a cloud-native enthusiast and tech blogger, sharing insights on Kubernetes, AWS, CI/CD, and Linux across my blog and Facebook page. Passionate about modern infrastructure and microservices, I aim to help others understand and leverage cloud-native technologies for scalable, efficient solutions.

Welcome to Day 20 — the final day of Week 3 in our Terraform series!
Today, we’ll dive into one of the most important production concepts in Terraform — remote state backends.
You’ll learn how to safely store, share, and protect Terraform state files in real-world team environments.


🎯 Learning Objectives

By the end of today, you will be able to:

✅ Configure remote backends (S3 or Terraform Cloud)
✅ Enable state locking using DynamoDB
✅ Read data from remote state files
✅ Manage multiple environments using isolated states
✅ Understand state isolation strategies and best practices


🧩 What Is Terraform State?

Terraform keeps track of your infrastructure resources in a file called terraform.tfstate.
This file acts as a record of what resources Terraform manages and their current attributes (like IDs, IPs, etc).

By default, this state is stored locally (on your machine).
That works fine for testing — but it’s risky for real production environments.


⚠️ Problems with Local State

When Terraform state is stored locally, you face several issues:

ProblemDescription
No collaborationOther team members can’t share or view the same state file
No lockingTwo users running Terraform at the same time can corrupt the state
No encryptionSensitive data like passwords or secrets may be stored in plain text
Risk of lossIf your laptop dies, your state is gone
No versioningYou can’t roll back to a previous state

✅ Why Use Remote State?

Remote backends solve all of these issues.
When you store your Terraform state remotely (for example, in S3 or Terraform Cloud), you get:

BenefitDescription
CollaborationShared state file accessible by all team members
State LockingPrevents simultaneous updates
EncryptionKeeps your state file secure
VersioningEasily roll back to previous versions
Audit TrailTracks who changed what and when

The most common backend setup for AWS-based projects is S3 + DynamoDB.

S3 stores the state file.
DynamoDB ensures state locking, preventing concurrent writes.


🧱 Basic S3 Backend Example

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "project/terraform.tfstate"
    region = "us-east-1"
  }
}

🧠 Explanation:

  • bucket: The name of your S3 bucket that stores state.

  • key: The path (like a folder) inside the bucket for the state file.

  • region: AWS region of the bucket.


🔒 S3 Backend with DynamoDB Locking

terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "project/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
    workspace_key_prefix = "workspaces"
  }
}

🧠 Explanation:

  • encrypt = true → Enables server-side encryption (AES-256).

  • dynamodb_table → Uses DynamoDB to lock the state during apply.

  • workspace_key_prefix → Keeps separate states for each workspace.


🏗️ Create Backend Infrastructure

Before configuring your backend, you must create the S3 bucket and DynamoDB table to store your state safely.

# backend-setup.tf
data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "terraform-state-${data.aws_caller_identity.current.account_id}"

  tags = {
    Name        = "Terraform State"
    Environment = "Production"
  }
}

resource "aws_s3_bucket_versioning" "terraform_state" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
  bucket = aws_s3_bucket.terraform_state.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

resource "aws_s3_bucket_public_access_block" "terraform_state" {
  bucket = aws_s3_bucket.terraform_state.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform-state-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }

  tags = {
    Name        = "Terraform State Locks"
    Environment = "Production"
  }
}

🧠 Explanation:

  • S3 Bucket: Stores Terraform state.

  • Versioning: Keeps history of changes to allow rollback.

  • Encryption: Protects your state file.

  • Public Access Block: Prevents public exposure.

  • DynamoDB Table: Manages state lock to prevent concurrent operations.


🔄 Initialize the Remote Backend

Migrating from Local to Remote

# Step 1: Add backend config

terraform {
  backend "s3" {
    bucket = "bucker-name
    key    = "prod/terraform.tfstate"
    region = "us-east-1"
  }
}

# Step 2: Initialize with migration
terraform init -migrate-state

# Step 3: Verify S3 file
aws s3 ls s3://bucket-name/prod/

Reconfiguring Backend

# To change backend settings
terraform init -reconfigure

# To migrate existing state forcefully
terraform init -migrate-state -force-copy

🧠 Backend Configuration Patterns

Terraform gives you multiple ways to provide backend configuration.

Keep sensitive values outside your code.

backend.tf

terraform {
  backend "s3" {}
}

backend-config/prod.hcl

bucket         = "prod-terraform-state"
key            = "infrastructure/terraform.tfstate"
region         = "us-east-1"
encrypt        = true
dynamodb_table = "prod-terraform-locks"

Initialize using:

terraform init -backend-config=backend-config/prod.hcl

🧩 Pattern 2: Environment Variables

export TF_CLI_ARGS_init="-backend-config=bucket=my-state-bucket"
terraform init

🧩 Pattern 3: Command Line Arguments

terraform init \
  -backend-config="bucket=my-state-bucket" \
  -backend-config="key=project/terraform.tfstate" \
  -backend-config="region=us-east-1"

🧱 State Isolation Strategies

State isolation ensures different environments (dev, staging, prod) do not interfere with each other.

1️⃣ Directory-Based Isolation

terraform/
├── dev/
│   └── backend.tf  # key = "dev/terraform.tfstate"
├── staging/
│   └── backend.tf  # key = "staging/terraform.tfstate"
└── prod/
    └── backend.tf  # key = "prod/terraform.tfstate"

Each environment has its own backend file and state file.


2️⃣ Workspaces

terraform {
  backend "s3" {
    bucket               = "terraform-state"
    key                  = "project.tfstate"
    workspace_key_prefix = "env"
    region               = "us-east-1"
  }
}

💡 Workspaces create automatically isolated state files:

s3://terraform-state/env/dev/project.tfstate
s3://terraform-state/env/prod/project.tfstate
terraform workspace new dev
terraform workspace select dev

☁️ Terraform Cloud Backend

Terraform Cloud provides a fully managed remote backend with versioning, state locking, and collaboration out of the box.

Basic Configuration

terraform {
  cloud {
    organization = "stackop"

    workspaces {
      name = "dev-workspace"
    }
  }
}

Using Multiple Workspaces

terraform {
  cloud {
    organization = "stackops"

    workspaces {
      tags = ["networking", "production"]
    }
  }
}

🎉 Summary

By now, you’ve learned how to:

✅ Configure and migrate to remote state
✅ Enable state locking with DynamoDB
✅ Organize environments using isolation strategies
✅ Use Terraform Cloud as an alternative backend

🚀 Day 21 Preview

Day 21: Workspaces for Environment Management

focuses on advanced techniques:

  • Workspaces

  • Terraform import

  • Provisioners

  • Testing strategies

  • CI/CD integration

  • Security best practices


← Day 19: Module Sources | Day 22: Workspaces →


Remember: Remote state is essential for team collaboration and production deployments!

More from this blog

S

StackOps - Diary

33 posts

Welcome to the StackOps - Diary. We’re dedicated to empowering the tech community. We delve into cloud-native and microservices technologies, sharing knowledge to build modern, scalable solutions.