Remote state & locking
State for teams, done safely.
A local state file works for one person, but the moment a team shares infrastructure it breaks: everyone has a different copy, and two people applying at once corrupt it. Remote state fixes both problems. A backend stores the single state file in shared storage — an S3 bucket, an Azure blob, Terraform Cloud, a GCS bucket — so everyone reads and writes the same state, and it can be encrypted and versioned centrally.
terraform {backend "s3" {bucket = "acme-tf-state"key = "prod/network/terraform.tfstate"region = "us-east-1"encrypt = true # encrypt state at restdynamodb_table = "acme-tf-locks" # state locking (see below)}}
Locking: the other half
Shared storage alone is not enough — without coordination, two simultaneous applies still race and corrupt state. Locking prevents that: before an operation, the backend takes a lock (in DynamoDB for S3, natively in Terraform Cloud/GCS), and a second apply waits or fails fast rather than colliding. So the two properties you need from a real backend are encryption at rest and locking; S3-plus-DynamoDB is the classic AWS combination that provides both.
$ terraform applyAcquiring state lock. This may take a few moments...# meanwhile, a teammate’s apply:Error: Error acquiring the state lockLock Info: ID: 3f0c..., Who: alice@acme, Created: 2m ago# → it refuses to run rather than corrupt shared state
Splitting state to limit blast radius
Beyond sharing, remote state lets you split one giant state into several — network, data, and app in separate state files (the key in the backend). Smaller states mean a smaller blast radius (a mistake in the app state cannot touch the network), faster plans, and clearer ownership. One state reads another’s outputs via a terraform_remote_state data source, which is how separated stacks still pass values to each other.