skip to content

Workspaces

CLI workspaces give one configuration several independent states in the same backend. The expected senior answer is why that is fine for ephemeral copies and a poor fit for real production isolation.

part ofTerraformoverview, primer and where to startread it →
on this pageshow

questions

5

In Terraform, what does a CLI workspace give you, and what actually changes when you run `terraform workspace select dev`?

level: juniorimportance: must knowfreq 62%

answer

  1. one configuration, several states
  2. the backend never changes
  3. select only swaps the state path
  4. terraform.tfstate.d locally
  5. env: prefix in S3

basics

~10 s

A Terraform CLI workspace is a separate state file for the same configuration in the same backend. Selecting one changes only which state Terraform reads and writes; the code, backend and credentials stay identical.

solid answer

~40 s

CLI workspaces let one root configuration hold several independent states inside a single backend. `terraform workspace new dev` creates an empty state named `dev`, `terraform workspace select dev` points later plans and applies at that state, `terraform workspace list` shows them all with a `*` on the active one, and `terraform workspace show` prints the active name. Nothing else changes: same `.tf` files, same backend block, same provider credentials, same `.terraform` directory, so you do not re-run `init` when switching. With the local backend, non-default workspaces live at `terraform.tfstate.d/<name>/terraform.tfstate`; with the S3 backend they land under the `env:` prefix, e.g. `env:/dev/<key>`. The `default` workspace always exists and cannot be deleted. HCP Terraform workspaces are a different, heavier concept.

code

bash · 5 lines
bash
terraform init
terraform workspace new dev
terraform workspace list
terraform workspace select default
terraform workspace show

go deeper

for a junior

Be able to say plainly that a workspace is a separate state for the same code, and name new, select, list and show. Knowing that default always exists earns easy credit.

for a middle

Explain the mechanics: where each workspace's state object actually lands locally and in S3, that .terraform and the backend are shared, and that inputs are the only legitimate way workspaces differ.

for a senior

Show you know the operational consequence — one backend, one credential set, one blast radius — and be ready to say which workloads you would and would not put in a workspace.

for a principal

Own the estate-level position: whether workspaces exist in your standard at all, what they are sanctioned for, and how you stop teams from quietly using them as an environment boundary.

## The one-sentence model A CLI workspace is a **named state file**, nothing more. One directory of `.tf` files, one backend, one set of provider credentials, and N independent states that the same configuration can be instantiated into. Switching workspaces swaps the state pointer, not the code. ## The commands ```bash terraform init # the backend must be initialized first terraform workspace list # default, dev (* marks the active one) terraform workspace new dev # creates an empty state AND selects it terraform workspace select dev # switches the active workspace terraform workspace show # prints just the active name terraform workspace delete dev # refuses while that state still has resources ``` `terraform workspace new` both creates and selects, which is why people are often surprised that their next `plan` shows every resource as new: they are planning against an empty state, not against the one they were just in. ## Where the state physically lands With the **local** backend the default workspace writes `terraform.tfstate` in the working directory, and every other workspace writes `terraform.tfstate.d/<workspace>/terraform.tfstate`. With the **S3** backend the default workspace uses the configured `key` unchanged, and non-default workspaces are prefixed: `env:/<workspace>/<key>`. The prefix is the `workspace_key_prefix` argument, whose default value is `env:`. So one bucket holds `prod/network.tfstate` for `default` and `env:/dev/prod/network.tfstate` for `dev`. Other backends have their own convention, but the principle holds: same backend configuration, different object path. ## What is shared, and why that matters later Because only the state path changes, everything else is shared across workspaces: - the backend block and therefore the bucket, table or server holding state; - the credentials the provider authenticates with; - the provider versions and modules already downloaded into `.terraform`, which is why switching does not require another `init`; - the configuration itself, so every workspace instantiates the *same* set of resources. The only legitimate way for two workspaces to differ is through **input values**: different `-var-file`s, different `TF_VAR_` environment variables, or expressions that branch on `terraform.workspace`. Terraform does not automatically load a `<workspace>.tfvars` file for you; if you want per-workspace inputs you pass them explicitly. ## The default workspace Every configuration has a workspace called `default` from the moment it is initialized. You never create it, you cannot delete it, and if you never run a workspace command you are silently working in it. That is why a fresh checkout on a CI runner — which has no local `.terraform/environment` file recording a selection — starts in `default`. ## Do not confuse it with an HCP Terraform workspace HCP Terraform (formerly Terraform Cloud) and Terraform Enterprise also call their units of work "workspaces", but those carry their own variables, run history, permissions and VCS connection. A CLI workspace carries none of that. Interviewers ask this deliberately, because candidates who have only used the SaaS product often describe features the CLI concept does not have. ## When it is the right tool The honest summary is: workspaces are good for *ephemeral or personal copies* of one stack in one account — a per-pull-request environment, a scratch copy while you test a refactor. They are a poor fit for prod-versus-staging separation, because sharing one backend, one credential set and one blast radius is exactly what real environment isolation is supposed to prevent.

  • After `terraform workspace new dev`, your plan wants to create everything again. Why?
    Because `new` creates an *empty* state and immediately selects it. The resources still exist in the previous workspace's state, but the active state knows nothing about them, so Terraform proposes creating them. Switch back with `terraform workspace select default`; if you genuinely meant to move resources, that is a state operation, not a workspace one.
  • Do you need to run `terraform init` again after switching workspaces?
    No. The backend configuration, provider plugins and modules in `.terraform` are shared across all workspaces of that working directory, so only the state path changes. You do need `init` before any workspace command, because the backend has to be initialized before Terraform can enumerate or create workspaces in it.
  • How does a CLI workspace differ from an HCP Terraform workspace?
    A CLI workspace is just a named state file in your backend. An HCP Terraform workspace is a server-side object with its own variable set, run queue, state history, permissions and VCS connection. The names collide but the concepts do not; describing HCP features when asked about the CLI is a common tell.

saying these in an interview costs you the question

  • Thinks each workspace gets its own backend or credentials
  • Believes workspaces can run different resource code
  • Claims switching workspaces requires another terraform init
  • Says the default workspace must be created or can be deleted
  • Describes HCP Terraform workspace features as CLI behaviour

context

open as a page

Why do most teams isolate production with a separate Terraform root module and backend rather than a CLI workspace?

level: seniorimportance: must knowfreq 60%

basics

~20 s

CLI workspaces share one backend, one access policy, one credential set and one configuration, so a mistake in the selected workspace can reach production. Separate root modules give each environment its own state store, permissions and blast radius.

open as a page

How is the `terraform.workspace` value typically used inside a Terraform configuration, and where does driving behaviour from it start to hurt?

level: middleimportance: should knowfreq 45%

basics

~20 s

terraform.workspace evaluates to the active workspace's name as a string. Configurations use it to prefix resource names or to look up per-workspace sizing, but branching real behaviour on it makes the same code mean different things in different states.

open as a page

A Terraform CI job applied against the default workspace instead of `staging`. How does Terraform decide which CLI workspace is active, and how do you make that deterministic in a pipeline?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Terraform reads the active workspace from .terraform/environment in the working directory. A fresh CI checkout has no such file, so it silently uses default. Make it explicit with TF_WORKSPACE or a terraform workspace select step after init.

open as a page

How do you correctly retire an ephemeral Terraform CLI workspace, and what happens if you run `terraform workspace delete` while its state still tracks resources?

level: middleimportance: nice to knowfreq 25%

basics

~20 s

Destroy inside the workspace first, then select another workspace and delete it. Terraform refuses to delete a workspace whose state still tracks resources unless you pass -force, which discards the state and orphans the real infrastructure.

open as a page