Skip to content
CloudOps
All prompts
AI for Terraform Difficulty: Intermediate ClaudeChatGPT

Terraform Workspaces vs Directory Structure Prompt

Choose between Terraform workspaces and directory-per-env — when each is appropriate, migration patterns.

Target user
Terraform engineers structuring multi-env deployments
Difficulty
Intermediate
Tools
Claude, ChatGPT

The prompt

You are a senior Terraform engineer who has built multi-environment setups using both workspaces and directory-per-env, with strong opinions on which fits which case.

I will provide:
- The environment count + characteristics
- Current structure
- Goal

Your job:

1. **Workspaces**:
   - Multiple state files via `terraform workspace`
   - Same backend, different keys
   - Same code, different state
   - `terraform.workspace` variable accessible
2. **Directory per env**:
   - Separate dirs: `envs/dev`, `envs/staging`, `envs/prod`
   - Each has own backend config
   - Code reuse via modules
   - Truly separate states
3. **When workspaces work**:
   - Many similar transient envs (review apps, branches)
   - Lightweight envs that share configuration
   - Single team managing all
   - Identical structure across envs
4. **When directories** (recommended for prod-like):
   - Real env separation
   - Different team ownership per env
   - Different cloud accounts
   - Different variable schemas
   - Promotion workflow (dev → staging → prod)
5. **For mixed approaches**:
   - Directories for prod tier separation
   - Workspaces within for variants
6. **For terraform.workspace pitfalls**:
   - Coding `count = terraform.workspace == "prod" ? 3 : 1` couples code to envs
   - Use variables instead
7. **For migration from workspaces → dirs**:
   - Pull state per workspace
   - Push to new backend per env
   - Update CI/CD
8. **For Terraform Cloud workspaces**:
   - Different concept; rich features (variables, runs, RBAC)
   - More like directory pattern but managed

Mark DESTRUCTIVE: confusing OSS workspaces with TFC workspaces, sharing prod and dev state in one backend, using workspaces for cross-account access.

---

Env count + characteristics: [DESCRIBE]
Current structure: [DESCRIBE]
Goal: [DESCRIBE]

Why this prompt works

This is a recurring architectural decision. This prompt walks tradeoffs.

How to use it

  1. For prod-like envs: directories.
  2. For ephemeral envs: workspaces.
  3. Don’t mix patterns without clear boundary.
  4. Migration: backup, transfer, verify.

Patterns

infrastructure/
├── modules/
│   ├── network/
│   ├── compute/
│   └── data/
├── envs/
│   ├── dev/
│   │   ├── main.tf           # module instantiation
│   │   ├── variables.tf
│   │   ├── terraform.tfvars  # dev values
│   │   └── backend.tf        # dev backend
│   ├── staging/
│   │   ├── main.tf
│   │   ├── terraform.tfvars
│   │   └── backend.tf
│   └── prod/
│       ├── main.tf
│       ├── terraform.tfvars
│       └── backend.tf
# envs/prod/main.tf
module "network" {
  source = "../../modules/network"

  cidr_block = var.cidr_block
  az_count   = var.az_count
}
# envs/prod/backend.tf
terraform {
  backend "s3" {
    bucket = "myorg-tfstate-prod"
    key    = "network/terraform.tfstate"
    region = "us-east-1"
  }
}
cd envs/prod
terraform init
terraform plan
terraform apply

Workspaces (for ephemeral / many similar)

# All workspaces use same backend
terraform workspace new pr-123
terraform workspace new pr-456

terraform workspace select pr-123
terraform plan -var="branch=pr-123"
terraform apply
# main.tf uses terraform.workspace
resource "aws_s3_bucket" "review" {
  bucket = "review-${terraform.workspace}"
}

Bad pattern (avoid)

# DON'T: coupling code to env names
resource "aws_instance" "web" {
  count = terraform.workspace == "prod" ? 3 : 1
  instance_type = terraform.workspace == "prod" ? "m5.large" : "t3.small"
}

# DO: parametrize
variable "instance_count" {}
variable "instance_type" {}

resource "aws_instance" "web" {
  count         = var.instance_count
  instance_type = var.instance_type
}

Comparison

AspectWorkspacesDirectory per env
State filesMultiple via same backendOne per dir
CodeSingleSingle (via modules)
VariablesSame setDifferent schemas allowed
Backend configOnePer env
Cross-accountNoYes (via provider)
PromotionSame code; switch workspaceSame module, different config
Team isolationHardEasy (dir permissions)
CI/CDSwitch workspacecd into dir

Migration from workspaces → dirs

# 1. Pull each workspace's state
for WS in dev staging prod; do
    terraform workspace select $WS
    terraform state pull > state-$WS.tfstate
done

# 2. Create directory structure
mkdir -p envs/{dev,staging,prod}
# Copy module references into each

# 3. Configure backend per dir
# envs/prod/backend.tf  →  s3 with key=prod/...

# 4. Push state per dir
cd envs/prod
terraform init                                # configures backend
terraform state push ../../state-prod.tfstate

# 5. Verify
terraform plan                                 # should be no changes

Common findings this catches

  • Single workspace state for dev + prod → split into directories.
  • terraform.workspace everywhere in code → parametrize.
  • Wrong workspace used in CI → directory pattern safer.
  • Cross-account via workspace → use provider per env directory.
  • Module changes affect prod and dev simultaneously → expected with workspaces; with dirs, separate promotion.
  • Workspace deletion → state file orphans (not destroyed).
  • TFC workspace ≠ OSS workspace → confusing.

When to escalate

  • Migration across many state files — staged.
  • Multi-team boundary changes — coordination.
  • Promotion workflow design — strategic.

Related prompts

Newsletter

Get weekly AI workflows for DevOps engineers

Practical prompts, automation ideas, and tool reviews for infrastructure engineers. One email per week. No spam.