Terraform Cheatsheet

Workspaces

Use this Terraform reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

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

CommandWhat it does
terraform workspace listlist all workspaces (* marks current)
terraform workspace showprint 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

WorkspacesSeparate root modules
Config duplicationNone — one configSome — copy or symlink
State isolationPer-workspace stateFully separate
Variable managementNeeds map lookupSeparate tfvars
Blast radiusShare providers/backend configFully isolated
Best forNear-identical envs, ephemeralSignificantly 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