TFLAB30-Workspaces: Managing Multiple Environments

Workspaces: Managing Multiple Environments

🔧 Terraform Core ⭐ Intermediate workspace terraform.workspace State Isolation

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