Terraform Advanced — Workspace & Directory Exercises

1 minute read

Practice environment management patterns.


Exercise 1 — Workspace-Based Config

Task: Write a locals block that maps workspace names to instance types and CIDR blocks.

Answer
locals {
  env = terraform.workspace

  config = {
    dev     = { instance_type = "t3.micro",  vpc_cidr = "10.0.0.0/16" }
    staging = { instance_type = "t3.small",  vpc_cidr = "10.1.0.0/16" }
    prod    = { instance_type = "m5.large",  vpc_cidr = "10.2.0.0/16" }
  }

  current = local.config[local.env]
}

Exercise 2 — Directory Layout

Task: Design a directory layout for 3 environments (dev, staging, prod) with 2 services (vpc, eks) and a shared modules directory.

Answer
infra/
├── modules/
│   ├── vpc/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── eks/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
├── dev/
│   ├── vpc/
│   │   ├── main.tf           # module "vpc" { source = "../../modules/vpc" }
│   │   └── terraform.tfvars
│   └── eks/
│       ├── main.tf
│       └── terraform.tfvars
├── staging/
│   ├── vpc/
│   └── eks/
└── prod/
    ├── vpc/
    └── eks/

Exercise 3 — Migration

Task: You have a workspace-based setup. How do you migrate to directory-per-environment without downtime?

Answer
# 1. Create new directory with same config
$ mkdir -p environments/prod

# 2. Copy config
$ cp *.tf environments/prod/

# 3. Pull state from workspace
$ terraform workspace select prod
$ terraform state pull > /tmp/prod.tfstate

# 4. Init new directory with new backend key
$ cd environments/prod
$ terraform init -backend-config="key=prod/terraform.tfstate"

# 5. Push state to new location
$ terraform state push /tmp/prod.tfstate

# 6. Verify — plan should show no changes
$ terraform plan
# No changes.

# 7. Repeat for each workspace

Chapter Summary

  • Workspaces: simple, one config, risk of applying to wrong env
  • Directories: explicit, isolated, but code duplication
  • Hybrid: directories for environments, workspaces for variations
  • Terragrunt: DRY + isolated + dependency ordering (best for large teams)
  • Production pattern: three-repo structure (modules, live, config)

← When to Use Each Chapter 4: Modules at Scale →

Updated: