Terraform · Part 11

Terraform — Part 11 — Managing Environments: Workspaces vs Directories

Every example so far has run against a single, implicit environment. This part covers the two real patterns for running the same configuration against dev, staging, and production without them colliding — and which one to actually reach for.

Quick idea: CLI workspaces give one configuration multiple named state files sharing the same backend and credentials; separate directories give each environment its own state, its own backend, and its own credentials entirely.
Workspace

A named state file within one working directory and one backend. Lightweight, same credentials for every workspace.

Directory

A completely separate copy of the configuration, with its own state, backend, and credentials.

default

The workspace every configuration starts in, and the one already used throughout this series.

Introduction

Every example in this series has run in a single, unnamed environment — one state file, one set of credentials, one backend. Real infrastructure work almost never stays that simple: the same configuration usually needs to exist in dev, staging, and production, without a change tested in dev being able to touch production by accident.

CLI Workspaces

Every configuration already has at least one workspace, named default — every apply in this series so far has run inside it without that ever being visible. A workspace is a named state file within the same working directory and the same backend:

# List existing workspaces (the current one is marked with *)
terraform workspace list

# Create and switch to a new workspace
terraform workspace new staging

# Switch to an existing workspace
terraform workspace select default

# Show which workspace is currently active
terraform workspace show

Inside a configuration, terraform.workspace resolves to the name of the currently active workspace, commonly used for naming or tagging so resources in different workspaces don’t collide:

resource "random_pet" "server" {
  prefix = "${terraform.workspace}-server"
  length = 2
}

Where Workspace State Lives

With local state, each non-default workspace’s state file lives inside a terraform.tfstate.d directory, one subfolder per workspace — treat that directory with the same care as a regular local state file. With a remote backend, the backend itself is responsible for keeping each workspace’s state separate, typically by appending the workspace name to the configured state path.

What Workspaces Are Good For

HashiCorp’s own guidance is that workspaces suit creating a parallel, disposable copy of infrastructure — testing a change in a workspace tied to a feature branch, for instance, without touching the workspace anything else is running in. Because a new workspace is nearly free to create and destroy, this fits short-lived, throwaway copies well.

What Workspaces Are Not Good For

The same guidance is direct about the limit: workspaces are not appropriate for system decomposition, and specifically not for the case where separate environments need separate credentials and access controls. Every workspace in a working directory shares the same backend configuration — the same credentials that can reach the staging workspace’s state can reach default‘s too.

Key rule: workspaces isolate state, not access. If dev and production genuinely need different credentials, different approval processes, or different people allowed to run apply, workspaces alone don’t provide that boundary.

The Alternative: Separate Directories

The other common pattern is simply running the same configuration from multiple working directories — environments/dev/, environments/staging/, environments/prod/ — each with its own backend configuration, and therefore its own credentials and its own genuinely separate state.

environments/
  dev/
    main.tf
    backend.tf
  staging/
    main.tf
    backend.tf
  prod/
    main.tf
    backend.tf

Each directory gets its own terraform init, its own provider plugin cache, and its own independent backend block — which is exactly what makes real credential separation possible: production’s backend can point at a bucket only a restricted set of people or pipelines can reach, while dev’s is open to the whole team.

Trade-off: separate directories mean separate everything — each one downloads and caches its own copy of every provider and module, and a shared configuration change has to be applied in each directory individually rather than automatically propagating.

Workspaces vs Directories

Aspect CLI Workspaces Separate Directories
Backend / credentials Shared across all workspaces. Independent per directory.
Setup cost Nearly free — one command to create. Higher — separate init, separate plugin cache per directory.
Best fit Short-lived, disposable copies (feature branches, PR previews). Genuinely distinct environments needing real access separation (dev vs prod).
Access control granularity None — same credentials reach every workspace. Full — each directory’s backend can require different credentials entirely.

Quick Reference Summary

Command Purpose
terraform workspace list Lists all workspaces in the current backend.
terraform workspace new <name> Creates and switches to a new workspace.
terraform workspace select <name> Switches to an existing workspace.
terraform.workspace Expression referencing the currently active workspace’s name.
terraform.tfstate.d Local directory holding non-default workspace state files.

Final Thoughts

Neither pattern is universally correct — the deciding factor is whether the environments genuinely need different access boundaries. A quick parallel copy for testing a branch is what workspaces were built for. Production needing its own credentials, separate from everything else, is what directories are built for.

Key takeaway: use workspaces for short-lived, same-credential copies of one environment; use separate directories the moment an environment needs genuinely different access controls — production almost always falls into the second category.
Next in this series

Terraform — Part 12 — Terraform Best Practices and Common Pitfalls. The capstone post, pulling together the practices from every earlier part into one working reference.