Free — no signup required

Remote Backends and Locking

3 min read

Moving Off Your Laptop

A backend in Terraform is the storage location for the state file. By default, Terraform uses a local backend — a file called terraform.tfstate in your working directory. To enable team collaboration, you move that file into shared cloud storage.

Common remote backends include:
- AWS S3 (paired with DynamoDB for locking)
- Google Cloud Storage (GCS) (with built-in locking via Cloud Storage object locks)
- Azure Blob Storage (with built-in lease-based locking)
- Terraform Cloud / HCP Terraform (managed backend with locking, history, and access controls built in)

You configure the backend inside the terraform {} block in your configuration. Once configured, Terraform automatically fetches the latest state from the remote location before every plan and uploads the updated state after every apply. The local machine becomes stateless — it's just a runner.

The Importance of Locking

Moving to the cloud solves sharing, but not concurrency. If two engineers run terraform apply simultaneously against the same remote state, they can still corrupt it by writing conflicting versions.

State locking solves this. Before Terraform begins any operation that could write to state, it attempts to acquire an exclusive lock on the state file.

  • In AWS, locking is implemented using a DynamoDB table. Terraform writes a lock record to the table before starting and deletes it when done.
  • If Engineer A holds the lock, Engineer B's Terraform run will immediately print an error like Error: Error locking state: Error acquiring the state lock and refuse to proceed.
  • If a Terraform process crashes mid-run and leaves a stale lock, you can manually release it with terraform force-unlock <LOCK_ID>. Use this carefully — only when you are certain no other process is actively running.

Backend Configuration Example

An S3 backend block declares a handful of fields, and each one matters:
- bucket: The S3 bucket that stores the state file. Must already exist — Terraform will not create it.
- key: The path within the bucket. Think of this as the filename. Use a structured path like <environment>/<layer>/terraform.tfstate to keep multiple state files organized.
- dynamodb_table: The DynamoDB table used for locking. Must have a partition key named LockID of type String.
- encrypt: Enables server-side encryption for the state file at rest.

Interview Tip

Interviewers frequently ask: "What happens if two engineers run terraform apply at the same time?" The answer is not "it merges the changes." The correct answer is: without locking, the last writer wins and the state becomes corrupted. With locking (e.g., DynamoDB), the second runner is blocked until the first completes. A follow-up question is often: "What do you do if a lock is stuck?" — answer: terraform force-unlock <LOCK_ID>, but only after confirming no active process holds it.

Key Point: The DynamoDB table and S3 bucket used for remote state are themselves infrastructure — but they must be created before Terraform can manage anything else. This is the classic bootstrapping problem. Teams typically create these resources once using the AWS CLI or a separate, minimal Terraform configuration with a local backend, then never touch them again.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free