Workspaces: Managing Multiple Environments
Scenario
You have one Terraform config that you want to use for dev, staging, and prod. Workspaces give you separate state files per environment while sharing the same code. The current workspace name is available as terraform.workspace.
Your Objectives
- Create workspaces: terraform workspace new dev, staging, prod.
- Use terraform.workspace in resource names and tags.
- Use a workspace-based lookup map for environment-specific values.
- Switch between workspaces and observe independent state.
Additional Context
Each workspace has its own state file. With local state, they're stored in terraform.tfstate.d/WORKSPACE_NAME/. With S3 backend, they're stored under env:/WORKSPACE_NAME/key. The default workspace is named default.
main.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" { region = "us-east-1" }
data "aws_caller_identity" "current" {}
# Workspace-based config lookup
locals {
env_config = {
dev = { versioning = false, tag = "development" }
staging = { versioning = true, tag = "staging" }
prod = { versioning = true, tag = "production" }
}
config = local.env_config[terraform.workspace]
}
resource "aws_s3_bucket" "app" {
bucket = "ws-demo-${terraform.workspace}-${data.aws_caller_identity.current.account_id}"
tags = {
Environment = local.config.tag
Workspace = terraform.workspace
ManagedBy = "terraform"
}
}
resource "aws_s3_bucket_versioning" "app" {
bucket = aws_s3_bucket.app.id
versioning_configuration {
status = local.config.versioning ? "Enabled" : "Suspended"
}
}Workflow Commands
terraform init
# Create and switch workspaces
terraform workspace new dev
terraform apply # creates bucket: ws-demo-dev-...
terraform workspace new prod
terraform apply # creates SEPARATE bucket: ws-demo-prod-...
terraform workspace list # shows all workspaces
terraform workspace select dev
terraform workspace show # prints current workspace name
# Each workspace has INDEPENDENT state
terraform state list # only shows dev resources
# Destroy each workspace's resources separately
terraform workspace select prod && terraform destroy
terraform workspace select dev && terraform destroy
✓ Workspace List
default * dev prod

