Terraform Cheatsheet
Workspaces
Use this Terraform reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
What Workspaces Are
Workspaces let you use the same configuration against multiple independent state files. Each workspace maintains its own state, so you can manage dev/staging/prod from a single root module without duplicating code.
Workspaces are not a substitute for separate root modules when environments differ significantly. They work best for near-identical environments (e.g., ephemeral feature environments).
Workspace Commands
| Command | What it does |
|---|---|
terraform workspace list | list all workspaces (* marks current) |
terraform workspace show | print current workspace name |
terraform workspace new <name> | create and switch to workspace |
terraform workspace select <name> | switch to existing workspace |
terraform workspace delete <name> | delete workspace (must not be current) |
terraform workspace new staging terraform workspace select prod terraform workspace list # * default # dev # staging # prod
terraform.workspace in Config
# Reference the current workspace name
locals {
env = terraform.workspace # "default", "dev", "staging", "prod"
}
resource "aws_instance" "web" {
instance_type = local.env == "prod" ? "t3.large" : "t3.micro"
tags = { Environment = local.env }
}
resource "aws_db_instance" "main" {
instance_class = terraform.workspace == "prod" ? "db.t3.medium" : "db.t3.micro"
}Per-Workspace Variables
Using a map lookup
locals {
config = {
dev = {
instance_type = "t3.micro"
min_capacity = 1
max_capacity = 2
}
staging = {
instance_type = "t3.small"
min_capacity = 1
max_capacity = 4
}
prod = {
instance_type = "t3.large"
min_capacity = 2
max_capacity = 10
}
}
env_config = local.config[terraform.workspace]
}
resource "aws_autoscaling_group" "app" {
min_size = local.env_config.min_capacity
max_size = local.env_config.max_capacity
}Using workspace-specific tfvars files
# Manually specify the right var file per workspace terraform apply -var-file="envs/${terraform.workspace}.tfvars"
# In CI, derive from workspace name WS=$(terraform workspace show) terraform apply -var-file="envs/${WS}.tfvars"
State File Layout per Backend
# S3 backend with workspaces s3://my-bucket/ ├── terraform.tfstate # default workspace └── env:/ ├── dev/terraform.tfstate ├── staging/terraform.tfstate └── prod/terraform.tfstate
The key from your backend config is used for the default workspace. Other workspaces nest under env:/<name>/.
Creating Ephemeral Environments
# Feature branch workflow terraform workspace new feature-auth terraform apply -var="image_tag=feature-auth-abc123" # ... test ... terraform destroy terraform workspace select default terraform workspace delete feature-auth
Workspace vs Separate State Files
| Workspaces | Separate root modules | |
|---|---|---|
| Config duplication | None — one config | Some — copy or symlink |
| State isolation | Per-workspace state | Fully separate |
| Variable management | Needs map lookup | Separate tfvars |
| Blast radius | Share providers/backend config | Fully isolated |
| Best for | Near-identical envs, ephemeral | Significantly different envs, strict isolation |
Workspace-Conditional Count
# Only create NAT gateway in prod (cost control) resource "aws_nat_gateway" "main" { count = terraform.workspace == "prod" ? 1 : 0 allocation_id = aws_eip.nat[0].id subnet_id = aws_subnet.public[0].id }
Switching Workspaces in CI/CD
# GitLab CI / GitHub Actions example
terraform workspace select ${ENVIRONMENT} || terraform workspace new ${ENVIRONMENT}
terraform plan -out=plan.tfplan
terraform apply plan.tfplan