Terraform & IaC

One Codebase, Multiple Stages: Workspaces

Lesson 13 of 14 · 10 min · Advanced

In real-world software delivery, you deploy identical infrastructure topologies across multiple environments: Development, Staging, QA, and Production. Terraform Workspaces allow you to manage distinct state files from a single set of configuration files.

The Multi-Environment Challenge

If you create a web application stack, you don't want to copy your .tf files into three separate folders (dev/, stage/, prod/) and manually keep them in sync every time you add a new resource. Workspaces keep one code directory and switch the active backend state underneath.

WorkspaceInstance TypeMin NodesDatabase Size
developmentt3.micro1db.t3.micro (Single-AZ)
stagingt3.small2db.t3.small (Single-AZ)
productionm5.large4db.r5.large (Multi-AZ)

Every Project Starts in "default"

If you have never run a workspace command, you are already using the default workspace. Creating new workspaces adds separate branches of state without changing your code.

Workspace Management CLI Commands

terminal
# 1. List all available workspaces
$ terraform workspace list
* default

# 2. Create and switch to a new 'dev' workspace
$ terraform workspace new dev
Created and switched to workspace "dev"!

# 3. Create 'prod' workspace
$ terraform workspace new prod

# 4. Switch between existing workspaces
$ terraform workspace select dev
Switched to workspace "dev".

# 5. Check which workspace is currently active
$ terraform workspace show
dev

Always Verify Active Workspace in Terminal

Because the folder looks identical on your disk, running terraform destroy in the wrong active workspace could accidentally destroy Production. Always run terraform workspace show or customize your shell prompt to display the active workspace.

Interpolating terraform.workspace in HCL

main.tf
locals {
  instance_types = {
    default = "t3.micro"
    dev     = "t3.micro"
    stage   = "t3.small"
    prod    = "m5.large"
  }
}

resource "aws_instance" "app" {
  ami           = "ami-0123456789abcdef0"
  instance_type = lookup(local.instance_types, terraform.workspace, "t3.micro")

  tags = {
    Name        = "app-server-${terraform.workspace}"
    Environment = terraform.workspace
  }
}

terraform.workspace Keyword

The terraform.workspace variable is built directly into Terraform's core engine. It always evaluates to the string name of the currently selected workspace.

How Remote State Isolates Workspaces

When using the AWS S3 backend, Terraform automatically prefixes the state object key with env:/<workspace_name>/. Your environments never overwrite each other's state data.

s3 bucket structure
s3://shan-tfstate-ap-south-1/
├── prod/app/terraform.tfstate                 # default workspace
├── env:/dev/prod/app/terraform.tfstate        # dev workspace
└── env:/stage/prod/app/terraform.tfstate      # stage workspace

Workspaces vs Directory-Based Layout

FactorTerraform WorkspacesDirectory-Based (e.g. environments/prod)
Code StructureSingle shared folder for all environmentsSeparate folder per environment referencing modules
Multi-Account CloudDifficult (all share same provider config)Easy (each folder has unique AWS Account IDs & IAM roles)
Blast RadiusHigh risk if engineer selects wrong workspaceLow risk (separate directories, separate permissions)
Configuration DriftZero code drift (all share exact same HCL)Requires discipline to keep module versions aligned
Best Use CaseFast ephemeral PR preview environments, dev/QAProduction multi-account enterprise architecture

The Enterprise Verdict

Use Workspaces For

  • Temporary pull request preview environments (e.g. pr-142).
  • Identical developer test sandboxes in the same AWS account.
  • Fast iteration when infrastructure differences are purely instance sizing.

Use Folder Separation For

  • Separate AWS Accounts (e.g. Dev Account vs Prod Account).
  • Strict compliance where Prod state must be locked behind distinct IAM roles.
  • Environments requiring structurally different architecture (e.g. Multi-Region in Prod).