Workspaces
A Terraform workspace is a named, separate state under the same configuration and backend — default, dev, prod. The same code, multiple independent states. With an S3 backend, each workspace's state lives at a derived key (env:/dev/...) inside the same bucket.
Workspaces are genuinely useful and routinely misused. They are a clean fit for lightweight, identical parallel copies of the same infrastructure — and a poor fit for the dev-vs-prod separation people most often reach for them to provide, because they share one backend and one set of credentials.
What a Workspace Is
You create and switch workspaces with three commands: terraform workspace new dev, terraform workspace select dev, and terraform workspace list. Each holds an independent state for the same configuration directory, so an apply in dev touches only dev's resources. The starting workspace is always default, and it cannot be deleted.
# create and switch in one step terraform workspace new dev # list; the active one is marked with * terraform workspace list # switch the active workspace terraform workspace select prod
The terraform.workspace Value
Inside the config, terraform.workspace resolves to the active workspace name, which you use to branch small differences — an instance count, a name suffix, a smaller machine type in non-prod. Kept to a few values, this is tidy. The moment it spreads into a dozen conditionals, each environment has quietly become a different code path threaded through one file, and the config gets hard to reason about.
resource "aws_instance" "web" { instance_type = terraform.workspace == "prod" ? "m5.large" : "t3.micro" tags = { Environment = terraform.workspace } }
Good Uses
Workspaces shine for ephemeral or parallel copies of identical infrastructure: a per-developer sandbox, a short-lived stack spun up for one pull request and torn down when it merges, a load-test environment that mirrors the real one. The defining trait is sameness — the same code, the same settings, just a separate state so the copies do not collide. When that is what you need, workspaces are the lightest tool for it.
Where Workspaces Fall Short
All workspaces share one backend and one provider configuration, which means one set of credentials and one account. That is weak isolation for prod versus dev: a leaked credential or a bad bucket policy exposes every workspace at once, and there is no account boundary between your sandbox and production. Worse, the active workspace is implicit — the same terraform apply hits a different environment depending on hidden CLI state — so forgetting to select is a real path to applying dev changes to prod.
Workspaces vs Directories
The recurring decision is workspaces versus separate directories (or separate backends) per environment. Workspaces minimize duplication but give weak isolation; separate directories duplicate a little code but give a real blast-radius boundary, per-environment backend config, and a distinct account for prod. Most teams land on isolating production with its own state and account, and reserving workspaces for the ephemeral identical copies they are actually good at. The organization chapter develops this trade-off in full.
Workspaces — share one config and one backend, so they are excellent for identical parallel copies but weak for prod isolation, since the active one is implicit and all share credentials. Choose them for ephemeral, identical stacks like per-developer or per-PR sandboxes.
Separate directories — give each environment its own state, backend config, and account, for real blast-radius isolation at the cost of some duplication. Choose them to keep production genuinely separate from dev and staging.
- Using workspaces to separate dev, staging, and prod, then applying to prod because you forgot to
workspace select— the same command targets a different environment based on hidden state. - Sprawling
terraform.workspaceconditionals through the config until each environment is effectively its own code path nobody can follow. - Assuming workspaces isolate credentials or accounts — they do not; all share the backend's and provider's auth.
- Forgetting which workspace is active and reading or approving a plan for the wrong environment.
- Deleting a workspace without first destroying its resources, orphaning everything that state tracked.
- Use workspaces for ephemeral, identical copies — per-PR or per-developer stacks — not for long-lived prod and dev separation.
- Isolate production with its own state, backend, and account rather than a workspace, for real blast-radius protection.
- Show the active workspace in your shell prompt so you never act on the wrong one.
- Keep
terraform.workspacebranching minimal; heavy divergence is the signal to split into directories. - Destroy a workspace's resources before deleting the workspace, so nothing is left orphaned.
Knowledge Check
What does a Terraform workspace isolate?
- The state — each workspace has its own state under the same config and backend
- The credentials and the AWS account, giving each workspace its own separate auth boundary
- The provider versions, so that each workspace can pin a different one of its own
- The backend itself, so that each workspace writes out to a different bucket
Which is a good use of workspaces?
- Spinning up an ephemeral, identical copy of the infrastructure per pull request
- Separating production from development to get real blast-radius isolation between them
- Giving the production environment its own distinct credentials and account
- Running two genuinely different configurations out of a single directory
Why are workspaces weak for prod-vs-dev separation?
- They share one backend and one set of credentials, so there is no account boundary between environments
- They cannot hold more than a single resource type within each one of them
- They require a wholly separate backend to be provisioned for every single workspace, which is costly to run
- They reset and wipe their state every single time you switch between them
What is the risk of the active workspace being implicit?
- The same
applytargets a different environment based on hidden CLI state, so forgetting to select can hit prod - Terraform applies the change to every one of the existing workspaces all at once, unless you explicitly opt out of it
- The default workspace is silently deleted the moment you create a new one alongside it
- Plans always run against the default workspace no matter which one you have selected
You got correct