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

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