Skip to main content

Terraform Workspace

A Terraform workspace is a named instance of state within a single backend configuration. Workspaces allow running the same Terraform configuration against separate state files — often used to manage dev, staging, and production environments from one codebase.

What Is a Terraform Workspace?

A Terraform workspace is a way to run the same configuration multiple times with separate state files — without duplicating any code.

Every Terraform configuration starts in a workspace called default. When you create a new workspace called staging, Terraform creates a second, completely separate state file. Your configuration code stays identical — only which state file Terraform reads and writes changes depending on which workspace is active.

Think of workspaces as named slots for state. Same code, different state slot, different real infrastructure.

Bash
+------------------------------------------+
| One S3 backend bucket |
| |
| env:/ |
| dev/ |
| payments-api/terraform.tfstate |
| staging/ |
| payments-api/terraform.tfstate |
| prod/ |
| payments-api/terraform.tfstate |
| payments-api/terraform.tfstate (default) |
+------------------------------------------+

Workspace Commands

Bash
# List all workspaces — asterisk marks the active one
terraform workspace list
# * default
# dev
# staging
# prod
# Create a new workspace
terraform workspace new staging
# Created and switched to workspace "staging"!
# You are now on a new, empty workspace. Workspaces isolate their state,
# so if you run "terraform plan" Terraform will not see any existing state
# for this configuration.
# Switch to an existing workspace
terraform workspace select prod
# Switched to workspace "prod".
# Show the current workspace
terraform workspace show
# prod
# Delete a workspace (must be empty — no resources in state)
terraform workspace delete dev

Using terraform.workspace in Configuration

The built-in terraform.workspace variable returns the name of the active workspace. Use it to drive environment-specific values:

HCL
# main.tf
locals {
# Different instance sizes per workspace
instance_type = {
default = "t3.micro"
dev = "t3.micro"
staging = "t3.small"
prod = "t3.large"
}
# Different replica counts per workspace
db_replica_count = {
default = 0
dev = 0
staging = 0
prod = 1
}
}
resource "aws_instance" "app" {
instance_type = local.instance_type[terraform.workspace]
# In dev workspace: t3.micro
# In prod workspace: t3.large
tags = {
Environment = terraform.workspace
Name = "swiggy-api-${terraform.workspace}-server"
}
}
resource "aws_db_instance" "main" {
replicas = local.db_replica_count[terraform.workspace]
}

Workspace Limitations — When NOT to Use Them

Workspaces are useful for short-lived environments (feature branches, PR previews) but have real limitations for permanent environment separation:

◈ DIAGRAM
+------------------------------------------+
| Workspace limitations |
| |
| Shared backend permissions: |
| If an engineer can access the backend, |
| they can access ALL workspace state |
| files — dev and prod alike |
| |
| No per-workspace access control: |
| You cannot restrict who can apply to |
| the prod workspace at the backend level |
| |
| Single backend configuration: |
| All workspaces share the same S3 bucket, |
| DynamoDB table, and IAM role |
+------------------------------------------+

For permanent environment separation (dev/staging/prod at a serious company), most teams prefer the directory-per-environment pattern:

Bash
infrastructure/
environments/
dev/
main.tf <- backend key: dev/terraform.tfstate
terraform.tfvars
staging/
main.tf <- backend key: staging/terraform.tfstate
terraform.tfvars
prod/
main.tf <- backend key: prod/terraform.tfstate
terraform.tfvars
modules/
vpc/
compute/
database/

Each environment directory has its own backend key, its own variable values, and can use separate AWS accounts with separate IAM permissions. A developer cannot accidentally apply to prod when working in the dev directory.

When Workspaces Are the Right Tool

  • Feature branch environments — spin up a temporary copy of staging for a PR, destroy it when the PR merges
  • Developer sandboxes — each engineer gets their own workspace to test changes
  • Short-lived test environments — load testing, chaos experiments, demo environments

Troubleshooting Workspaces

Error Root Cause Fix
Workspace does not exist Wrong workspace name Run terraform workspace list to see available workspaces
Cannot delete workspace with resources State is not empty Run terraform destroy in that workspace first
Resources look wrong after workspace switch Forgot to switch workspace Run terraform workspace show to confirm active workspace
terraform.workspace returns default Never created named workspaces Run terraform workspace new <name>
Common Mistake

Using workspaces as the primary mechanism to separate prod from dev in a large team. Workspaces share backend permissions — anyone who can apply to dev can also apply to prod. For strict environment isolation, use separate directories with separate backend keys and, ideally, separate AWS accounts.

Frequently Asked Questions

How is a Terraform workspace different from just using separate directories per environment?

Workspaces share a single backend configuration and the same .tf files, switching only which state file is active (`terraform.tfstate.d/<workspace>`) via `terraform workspace select`. Directory-per-environment instead duplicates or symlinks configuration across folders, each with its own backend block. Workspaces reduce duplication for near-identical environments but keep all environments coupled to one codebase — a bad module change risks all of them at once.

Why do many teams avoid workspaces for prod vs. dev separation?

Because workspaces don't isolate variables, IAM credentials, or backend access by default — a `terraform.workspace` conditional (`count = terraform.workspace == "prod" ? 1 : 0`) is easy to get wrong, and a stray `terraform apply` while on the wrong workspace can hit production. HashiCorp itself now recommends separate root configurations (or Terragrunt/Terraform Cloud workspaces with distinct state backends and access controls) for environments with materially different risk profiles.