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.
+------------------------------------------+| 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
# List all workspaces — asterisk marks the active oneterraform workspace list# * default# dev# staging# prod # Create a new workspaceterraform 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 workspaceterraform workspace select prod# Switched to workspace "prod". # Show the current workspaceterraform workspace show# prod # Delete a workspace (must be empty — no resources in state)terraform workspace delete devUsing terraform.workspace in Configuration
The built-in terraform.workspace variable returns the name of the active workspace. Use it to drive environment-specific values:
# 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:
+------------------------------------------+| 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:
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 MistakeUsing 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.