Beyond S3, what other backend types does Terraform support, and how do they compare?

5 minintermediateterraformbackendstate

Quick Answer

S3 (with native locking or a DynamoDB table) is the most common backend for AWS-centric teams, but Terraform supports many others: **azurerm** (Azure Blob Storage, using blob leases for locking), **gcs** (Google Cloud Storage, with built-in locking), **consul** (a Consul KV path, common in on-prem/HashiCorp-stack shops), **remote/cloud** (Terraform Cloud/HCP Terraform, which layers locking, run history, and RBAC on top of managed remote state), and **kubernetes** (storing state in a ConfigMap/Secret, natural for teams already centered on a Kubernetes control plane). Which one to pick usually follows your primary cloud/platform, and whether you want a fully managed experience (Terraform Cloud) versus operating the storage yourself (S3/GCS/Azure Blob).

Detailed Answer

The backend block determines where Terraform stores its state and how it coordinates locking — and the right choice usually just follows whichever platform your organization already lives on.

S3 (AWS)

terraform {
  backend "s3" {
    bucket         = "my-org-tfstate"
    key            = "prod/network/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"   # or use native S3 locking on newer versions
    encrypt        = true
  }
}

The most common choice for AWS-centric teams. Locking historically required a separate DynamoDB table (conditional writes); newer AWS provider/Terraform versions support S3-native locking without it.

azurerm (Azure)

terraform {
  backend "azurerm" {
    resource_group_name  = "tfstate-rg"
    storage_account_name = "tfstateacct"
    container_name       = "tfstate"
    key                  = "prod.terraform.tfstate"
  }
}

Stores state in Azure Blob Storage; locking is implemented using blob leases, native to the storage service — no separate locking resource needed.

gcs (Google Cloud)

terraform {
  backend "gcs" {
    bucket = "my-org-tfstate"
    prefix = "prod/network"
  }
}

Google Cloud Storage backend, with built-in object locking — again, no extra locking resource required, similar to Azure's approach.

consul

Stores state under a key in a Consul KV store. Common in organizations already running Consul for service discovery/configuration as part of the broader HashiCorp stack, less common as a first choice otherwise.

remote / cloud (Terraform Cloud / HCP Terraform)

terraform {
  cloud {
    organization = "my-org"
    workspaces {
      name = "prod-network"
    }
  }
}

Rather than pointing at a storage bucket you manage yourself, this delegates state storage, locking, run history, and RBAC entirely to HashiCorp's managed (or self-hosted Enterprise) platform.

kubernetes

Stores state as a Kubernetes Secret, letting teams whose primary control plane is Kubernetes avoid standing up a separate cloud storage bucket purely for Terraform state.

Choosing among them

In practice, the decision is rarely "which backend is technically best" — it's almost always "which platform does this team already operate on." An AWS-only shop uses S3; an Azure-only shop uses azurerm; a team already invested in Terraform Cloud/HCP Terraform for its governance features uses the cloud block. Mixing backend providers across unrelated clouds is uncommon, since it adds an extra piece of infrastructure (and cross-cloud IAM) purely to host state files.

Related Resources