Mission 6.1 · Stage 6 — Environments
Workspaces vs Separate Backends
Goal: Try CLI workspaces on ShopLite, see exactly where they help and where they bite, and decide on the environment strategy for the rest of the course.
By the end of this mission
- Create and switch workspaces and see where their state is stored
- Use
terraform.workspacein expressions — and know why it's risky - List the trade-offs between workspaces and per-environment backends
Part 1
Understand it first
What a workspace is
A CLI workspace is a named, separate state file for the same configuration and backend. default is the one you've been using. terraform workspace new staging creates another; with the S3 backend its state lives at env:/staging/<your key>. Same code, same backend settings, different state.
It's the quickest way to get a second copy, which is why tutorials love it.
Why many teams avoid workspaces for environments
The selected workspace is invisible local state: nothing in the code or the command line says which environment you're about to change. terraform apply in the wrong workspace is one forgotten workspace select away.
Workspaces also share ONE backend and therefore one set of credentials and usually one AWS account, while prod should be isolated in its own account (Mission 6.3). Differences between environments tend to become terraform.workspace == "prod" ? ... : ... expressions scattered through the code. HashiCorp's own docs say workspaces aren't suitable for isolating environments with different credentials and access controls.
The alternative: same code, separate backend config + tfvars
Keep one root configuration, but give each environment its own backend settings file (bucket, key, even a different account's role) and its own .tfvars. You choose the environment explicitly on every command, and a wrapper script makes it one argument: ./tf prod plan. Everything that differs lives in two small, reviewable files per environment. This course uses that from Mission 6.2 on.
A third approach, one directory per environment calling a shared 'stack' module, adds per-environment module version pinning. It's common in large organisations, and you'll recognise it after Stage 5.
Part 2
Your project after this mission · 0 files change
- infra/
- alb.tf
- backend.tf
- checks.tf
- database.tf
- ecr.tf
- ecs.tf
- iam.tf
- locals.tf
- logs.tf
- main.tf
- outputs.tf
- probe.tf
- providers.tf
- refactors.tf
- security.tf
- storage.tf
- terraform.tfvars
- uploads.tf
- variables.tf
- versions.tf
Part 3
Build it, step by step
- 1
Create a workspace and look around
The new workspace has an empty state, so
state listprints nothing. Nothing exists here yet.terminal$ terraform workspace listterraform workspace new stagingterraform state list | wc -l── expected output ──* defaultCreated and switched to workspace "staging"!You're now on a new, empty workspace. Workspaces isolate their state,so if you run "terraform plan" Terraform will not see any existing statefor this configuration.0 - 2
See where its state would live
The S3 backend prefixes non-default workspaces with
env:/<name>/. Theworkspace_key_prefixsetting changes the prefix, but not the fact that it's the same bucket and the same credentials.terminal$ terraform plan -var environment=staging -var vpc_cidr=10.25.0.0/16 -out=ws.tfplan >/dev/nullaws s3 ls s3://shoplite-tfstate-c41e --recursive | grep tfstate$── expected output ──2026-09-26 11:02:17 9214 bootstrap/terraform.tfstate2026-09-26 16:40:12 155 env:/staging/shoplite/dev/terraform.tfstate2026-09-26 16:31:08 211877 shoplite/dev/terraform.tfstateNote the key still says 'dev', because the backend block is shared. Workspaces can't vary the backend. - 3
Clean up the experiment
Switch back and delete the workspace. You can't delete the workspace you're in, and Terraform refuses to delete one whose state isn't empty (this one never applied).
terminal$ rm ws.tfplanterraform workspace select defaultterraform workspace delete staging── expected output ──Switched to workspace "default".Deleted workspace "staging"!
Checkpoint — you should now have
- ✓You've seen where workspace state lives (
env:/<name>/...) in the same bucket. - ✓You can list three reasons not to use workspaces for dev/prod isolation.
- ✓The
stagingworkspace is deleted; you're back ondefault.
Part 4
Break it on purpose
Make each change, run the command, and read the error before revealing the diagnosis. Recognising these messages on sight is what makes you fast on a real team. Undo the change afterwards.
Break #1
Apply a second environment with the same names
In a staging workspace, run terraform apply -var vpc_cidr=10.25.0.0/16, forgetting to also change environment (it's still dev from tfvars).
Part 5
Interview questions from this mission
What are Terraform CLI workspaces, and when are they appropriate?
How do you structure Terraform for multiple environments?