DevOpsLesson
DevOpsLesson

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Stay Updated

Get notified about new tutorials and features.

Tutorials

  • What is DevOps?
  • Docker Tutorial
  • Terraform Tutorial
  • CI/CD Pipeline
  • All Tutorials

Roadmaps

  • DevOps Engineer
  • Cloud Engineer
  • SRE Path
  • All Roadmaps

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 DevOpsLesson. All rights reserved.

DOCKERKUBERNETESTERRAFORMAWSCI/CDLINUXGITDEVOPS ROADMAPCLOUD ROADMAPSRE ROADMAPGIT CHEATSHEETDOCKER CHEATSHEETK8S CHEATSHEETTF CHEATSHEETLINUX CHEATSHEETDOCKERFILE LINTERYAML VALIDATORCRON PARSERREGEX TESTER

Terraform Tutorial

Introduction to Terraform
Installing Terraform
The Terraform Core Workflow
Terraform Variables and Outputs
Terraform State and Backends
Terraform Modules
Terraform Data Sources
Terraform Count and for_each
Terraform Expressions and Functions
Terraform Dynamic Blocks
Terraform Workspaces
Terraform with AWS
Terraform Provisioners
Terraform CI/CD Pipeline
Terraform Security

Terraform Remote Backends

PreviousPrev
Next

Learn why Terraform remote backends matter, how to configure S3 with DynamoDB locking, when to use Terraform Cloud or GCS, and how to migrate state safely.

Why Remote Backends Matter

When you first learn Terraform, state usually lives in a local terraform.tfstate file. That is fine for practice, but it breaks down quickly in real teams.

Imagine a shared production environment where:

  • several engineers work on the same Terraform codebase
  • CI/CD pipelines run Terraform automatically
  • state may contain secrets and internal infrastructure details
  • you need a reliable way to avoid concurrent writes

Local state is not designed for that. A remote backend solves these problems by storing state in a shared external system.

In Terraform, a backend determines where state is stored and how Terraform interacts with it.

Remote backends matter for three big reasons:

1. Team collaboration

Everyone works from the same source of truth. The state is not trapped on one developer laptop.

2. CI/CD compatibility

Pipelines can run Terraform without depending on a local file that only one person has.

3. Better security and durability

State can be stored in protected infrastructure such as S3, Terraform Cloud, or GCS, with access controls, encryption, backup, and audit features.

What a Backend Does

A backend is configured in the terraform block.

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

The backend is not a provider resource. It is part of Terraform's own configuration. It tells Terraform where to store and read state.

Backends may also provide extra capabilities such as:

  • state locking
  • encryption settings
  • workspace support
  • remote execution features in managed platforms

Why Teams Prefer Remote Backends

Let us compare local and remote state in practical terms.

ConcernLocal StateRemote Backend
Shared accessPoorStrong
CI/CD usageAwkwardNatural
DurabilityDepends on one machineStored centrally
LockingUsually weak or absentOften supported
Access controlFile-system basedCloud IAM / platform ACLs
BackupsManualEasier with backend features

For production, remote state is the standard pattern.

S3 + DynamoDB Backend: The Most Common AWS Pattern

On AWS, the most common remote backend uses:

  • Amazon S3 to store the state file
  • Amazon DynamoDB to manage the lock

This combination is popular because it is simple, durable, and integrates well with existing AWS IAM policies.

Full S3 backend configuration example

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

What each argument means

  • bucket: the S3 bucket that stores the state file
  • key: the path-like object name inside the bucket
  • region: AWS region where the bucket exists
  • dynamodb_table: the table Terraform uses for locking
  • encrypt: enables server-side encryption for the stored object

Example bootstrap infrastructure for the backend

You usually create the backend infrastructure once before using it.

resource "aws_s3_bucket" "terraform_state" {
  bucket = "devopslesson-terraform-state"
}

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"
  }
}

Why versioning matters

S3 versioning is highly recommended. If state is overwritten accidentally or corrupted, versioning gives you recovery options.

State Locking with DynamoDB

Locking prevents two Terraform operations from writing to the same state at the same time.

Here is the problem without locking:

  1. Engineer A runs terraform apply
  2. Engineer B runs terraform apply before A finishes
  3. both read the same starting state
  4. both make changes
  5. both try to write updated state

This can produce broken or inconsistent state.

With DynamoDB locking, Terraform first tries to create a lock entry. If the lock already exists, the second operation waits or fails.

Conceptual flow

terraform apply
  -> request lock from DynamoDB
  -> if lock acquired, read state from S3
  -> run plan and apply changes
  -> write updated state back to S3
  -> release lock in DynamoDB

This pattern is a major reason S3 + DynamoDB is considered production-friendly.

Backend Configuration and terraform init

After you add or change a backend block, Terraform needs to initialize it.

terraform init

If local state already exists, Terraform typically asks whether it should migrate that state into the configured remote backend.

This is one of the most convenient parts of Terraform: it can move your state for you during initialization.

Partial Backend Configuration

Teams often avoid hardcoding every backend detail in source code, especially values that vary per environment.

A common pattern is partial backend configuration.

In code

terraform {
  backend "s3" {}
}

In a backend config file

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

Then initialize with:

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

This pattern is helpful when:

  • each environment has a different key path
  • backend settings should be selected by automation
  • you want cleaner reusable Terraform code

You can also pass multiple -backend-config flags if needed.

Why partial backend config is useful in CI/CD

In CI/CD, a pipeline may choose a backend config based on branch, workspace, or deployment environment. That keeps the Terraform code generic while the pipeline controls where state actually lives.

Terraform Cloud Backend

Terraform Cloud is HashiCorp's managed platform for Terraform workflows.

A simple backend configuration looks like this:

terraform {
  cloud {
    organization = "devopslesson"

    workspaces {
      name = "production"
    }
  }
}

Why teams choose Terraform Cloud

Terraform Cloud can provide:

  • managed remote state
  • locking
  • run history
  • variable management
  • policy controls in higher tiers
  • remote execution in the platform

This can be a great option for teams that want less backend infrastructure to manage themselves.

When Terraform Cloud is attractive

  • you want a managed experience
  • you want a UI for plans and applies
  • you want centralized variable management
  • you want remote runs rather than local execution

GCS Backend (Briefly)

On Google Cloud, a common backend choice is Google Cloud Storage.

Example:

terraform {
  backend "gcs" {
    bucket = "devopslesson-terraform-state"
    prefix = "network/prod"
  }
}

The idea is similar to S3:

  • state is stored centrally
  • access is controlled by cloud IAM
  • the backend is durable and shareable

The exact details differ by platform, but the mental model stays the same.

Migrating State from Local to Remote

A very common workflow is:

  1. start learning with local state
  2. decide the project needs collaboration or CI/CD
  3. add a remote backend
  4. migrate state

Terraform makes this easier than many beginners expect.

Basic migration flow

  1. add the backend block to your configuration
  2. run terraform init
  3. Terraform detects existing local state
  4. Terraform asks whether you want to copy it to the new backend
  5. confirm the migration

Terraform then stores future state in the remote backend.

Why this is powerful

You do not normally need to manually copy JSON files around. Terraform handles the migration logic safely through initialization.

Workspace Concept Briefly

Terraform workspaces let you maintain multiple state snapshots for the same configuration.

For example, you might have:

  • default
  • dev
  • staging
  • prod

Each workspace has separate state.

This sounds convenient, but beginners should use workspaces carefully. They are helpful in some situations, but many teams prefer separate directories, separate backends, or separate root modules for strongly isolated environments.

A simple way to think about workspaces is:

  • same code
  • different state
  • optional environment separation mechanism

Security Best Practices for Remote Backends

Remote state is better than local state for teams, but you still need to secure it properly.

For S3 backends

  • enable bucket encryption
  • block public access
  • enable versioning
  • restrict bucket access with IAM
  • restrict DynamoDB table access to Terraform users and pipelines only

For all remote backends

  • follow least-privilege access
  • separate environments where appropriate
  • audit who can read or write state
  • remember that state may contain secrets

Common Beginner Mistakes

Treating the backend like a provider resource

The backend is configured in the terraform block, not created with a normal resource block inside the same initialized workflow.

Committing backend secrets carelessly

Be careful with credentials and backend config patterns. Backend config files may still reveal structure, even if they do not directly contain secrets.

Forgetting to re-run terraform init

Whenever backend configuration changes, terraform init is required.

Assuming remote state removes all security concerns

Remote backends improve security, but access still needs to be locked down properly.

Best Practices

  1. Use remote backends for shared environments.
  2. Prefer S3 + DynamoDB on AWS if you want a proven standard pattern.
  3. Enable encryption and versioning for backend storage.
  4. Use locking to avoid concurrent writes.
  5. Use partial backend configuration when environments differ.
  6. Run terraform init after backend changes.
  7. Protect backend access with strong IAM or platform permissions.

Final Thoughts

Remote backends are what turn Terraform from a personal tool into a team-ready platform. They centralize state, make CI/CD practical, improve durability, and reduce the risk of conflicting updates.

For AWS teams, S3 with DynamoDB locking is the most common starting point because it is simple and reliable. For teams that want a managed experience, Terraform Cloud is an excellent alternative. On Google Cloud, GCS fills a similar role.

The key idea is straightforward:

  • local state is fine for learning
  • remote state is the standard for teams
  • locking is essential for safe collaboration
  • terraform init handles migration when you switch backends

Once you understand remote backends, you are ready to manage Terraform state much more safely in real environments.

A practical habit for teams is to decide backend strategy early: one backend per environment, clear naming for state keys, locked-down access, and documented initialization steps. That small investment prevents confusion later when projects, teams, and automation pipelines all start touching the same infrastructure.


Knowledge Check

Exercise

Question 1: Why Remote Backends

What is one of the biggest reasons teams move from local state to a remote backend?

Exercise

Question 2: S3 and DynamoDB

In the common AWS remote backend pattern, what are S3 and DynamoDB each used for?

Exercise

Question 3: Migration

How do teams usually migrate Terraform state from local storage to a new remote backend?

PreviousPrev
Next

Continue Learning

Terraform Output Values

Learn Terraform output values in depth, including output blocks, sensitive outputs, terraform output commands, module outputs, and CI/CD automation patterns.

10 min read·Easy

Terraform State and Backends

Learn the big picture of Terraform state, remote backends, and state management commands so you can work safely with real infrastructure and collaborate with confidence.

5 min read·Medium

Terraform State Overview

Learn what Terraform state is, why the terraform.tfstate file exists, how it maps to real infrastructure, and why state security and locking matter in production.

12 min read·Medium

Explore Related Topics

AW

AWS Tutorials

Provision AWS infrastructure with Terraform

CI

CI/CD Tutorials

Run terraform plan/apply in CI pipelines

Try the Tool

YAML Validator

Validate Terraform and Kubernetes YAML configs before applying.

On This Page

Why Remote Backends Matter1. Team collaboration2. CI/CD compatibility3. Better security and durabilityWhat a Backend DoesWhy Teams Prefer Remote BackendsS3 + DynamoDB Backend: The Most Common AWS PatternFull S3 backend configuration exampleWhat each argument meansExample bootstrap infrastructure for the backendWhy versioning mattersState Locking with DynamoDBConceptual flowBackend Configuration and `terraform init`Partial Backend ConfigurationIn codeIn a backend config fileWhy partial backend config is useful in CI/CDTerraform Cloud BackendWhy teams choose Terraform CloudWhen Terraform Cloud is attractiveGCS Backend (Briefly)Migrating State from Local to RemoteBasic migration flowWhy this is powerfulWorkspace Concept BrieflySecurity Best Practices for Remote BackendsFor S3 backendsFor all remote backendsCommon Beginner MistakesTreating the backend like a provider resourceCommitting backend secrets carelesslyForgetting to re-run `terraform init`Assuming remote state removes all security concernsBest PracticesFinal ThoughtsKnowledge Check