Terraform "workspaces" are convenient, but they are not a universal isolation boundary. Environment separation is designed by combining account separation, directory separation, and workspace separation.
Based on the official documentation, this article walks through the points commonly tested on the exams (Associate / Pro) and the judgment criteria that teams find tricky in day-to-day operations, with concrete examples.
A Terraform CLI workspace is "a mechanism that splits the state file by name inside a single configuration directory." On supported backends (local and several remote backends), non-default workspaces keep their own separate state.
A Terraform Cloud/Enterprise (TFC/TFE) "workspace" is a first-class object that encapsulates state, variables, runs, and policies. The name is the same as a CLI workspace, but the function and operational unit differ (do not confuse them).
Important point: a workspace is not a "permission boundary." When you need strong isolation (production protection, billing/IAM separation), prefer separation by cloud account/project or a separate backend.
The big picture of environment separation (permission boundary vs. state boundary)
Org/Company
├─ Cloud Accounts/Projects (strong permission boundary)
│ ├─ prod-account
│ │ └─ TF Backend (prod) ── Workspaces/TFC Workspace(s): [prod]
│ └─ nonprod-account
│ └─ TF Backend (nonprod) ── Workspaces/TFC Workspace(s): [dev, stg]
└─ Repo/Directory (logical structure separation)
├─ envs/prod
├─ envs/stg
└─ envs/devBasic CLI workspace operations
terraform workspace list
terraform workspace new dev
terraform workspace select dev
terraform workspace showIn real implementations, you combine multiple isolation layers. The table below compares representative patterns. The exam also asks "which isolation is the best fit for the requirements."
If you cannot tolerate the risk of accidental changes to production, start by considering account/project separation and a separate backend, and use workspaces as a complementary tool — that is the safer approach.
| Pattern | Isolation level / use case | Pros | Cautions / risks |
|---|---|---|---|
| Account/project separation (AWS Account / GCP Project / Azure Subscription) | Strongest isolation. Billing, IAM, and API limits are also independent. Best for production protection. | Minimum blast radius; easy compliance alignment | Higher operational cost. Cross-account integration design is required |
| Directory/repository separation (config per env) | Effective when structural differences are large. Easier to split review units. | Change impact is easy to read; simpler CI | Hard to maintain without modularizing duplicates |
| Workspace separation (CLI/TFC) | Minor diffs of the same configuration (dev/stg/prod, etc.) | State is auto-separated; switching is easy | Not a permission boundary. Watch for mis-selection risk |
| Single workspace + variable switching only | Minimum setup for validation use | Minimal management | Unsuitable for environment separation. A misapply is highly damaging |
S3 backend example (state file layout with workspace support)
terraform {
backend "s3" {
bucket = "example-tfstate"
key = "network/terraform.tfstate" # the default workspace uses this key
region = "ap-northeast-1"
dynamodb_table = "tf-lock"
encrypt = true
}
}
# Example: most remote backends namespace non-default workspaces
# as env:/<workspace>/network/terraform.tfstate (backend-implementation dependent).Consistency in naming is the most important thing. Keep workspace names short and lowercase, fixed to dev/stg/prod. Use terraform.workspace in resource names and tags to improve observability.
Split variables per environment with tfvars and select them via -var-file in CI. In TFC, use Workspace variables and Variable Sets, and never place secrets in VCS.
Push "environment differences" into module input variables and minimize conditional branching. When the diff grows large, splitting the directory and changing the configuration itself is safer.
Best practices for resource naming and variables
locals {
common_tags = {
managed_by = "terraform"
env = terraform.workspace
}
}
resource "aws_s3_bucket" "logs" {
bucket = "app-logs-${terraform.workspace}"
tags = local.common_tags
}
# Example: select per-environment tfvars in CI
# dev:
# terraform workspace select dev
# terraform apply -var-file=env/dev.tfvars
# prod:
# terraform workspace select prod
# terraform apply -var-file=env/prod.tfvarsWorkspaces are convenient, but they are not a permission boundary. When you keep prod and dev in the same account and the same backend, the risk of a misapply due to a wrong workspace select remains. In CI, run explicit workspace verification and use protected branches.
Trying to absorb backend and provider differences with workspaces alone leads to complexity. When the region or account differs, use provider aliases and explicit variables for control, and split the configuration once you exceed those limits.
Moving state requires care. Movement between workspaces is not a simple terraform state mv. Understand pull/push and plan the move carefully.
Moving state between workspaces (for verification only; always back up)
# Source: the dev workspace
terraform workspace select dev
terraform state pull > tfstate-dev.json
# Destination: the prod workspace (confirm the configuration is identical)
terraform workspace select prod
terraform state push tfstate-dev.json
# Note: state mv moves addresses inside the same state. Use pull/push to move across workspaces.In TFC/TFE, the base pattern is "one stack x one environment x one workspace": assign prod/stg/dev to individual workspaces. Manage shared values via Variable Sets and environment-specific values via Workspace variables, and protect them with RBAC and policies.
State locking and concurrency control are guaranteed by the platform. Implement production guardrails with Run Tasks and policy sets (Sentinel/OPA) to suppress accidental changes.
Basic Terraform Cloud backend setup (bound by name)
terraform {
cloud {
organization = "acme"
workspaces {
name = "app-prod" # create a separate workspace per environment
}
}
}
# Or when combining with the CLI workspace, prepare a same-named TFC workspace
# and run terraform workspace select explicitly in CI.Frequently tested on Associate/Pro: "can you choose the appropriate pattern for the isolation requirements?", "the difference between CLI and TFC workspaces", and "how to handle backends and locks." Mastering the following points directly translates to scoring.
Commands, the default workspace behavior (key handling), state handling (lock, pull/push), and -var-file operation are tested straightforwardly.
Short cheat sheet
# New workspace
terraform workspace new stg
# Switch
terraform workspace select stg
# Run (explicit variable file)
terraform plan -var-file=env/stg.tfvars
terraform apply -var-file=env/stg.tfvars
# List/show
terraform workspace list
terraform workspace showAssociate / Pro
問題 1
Organizational requirements: production must be strictly isolated (separate IAM, separate billing); dev/staging should be cost-optimized while managed with the same configuration. Which strategy is most appropriate?
正解: A
Strong isolation (IAM/billing) is achieved with account/project separation and a separate backend. Protect production via a TFC Workspace and policy. Non-production is often sufficient with workspace separation. B/C provide insufficient production protection; D has a weak boundary inside the same account.
Is a workspace a sufficient boundary to protect production?
No. A workspace is only a logical separation of state — it is not an IAM, network, or billing boundary. The recommended approach is to isolate production with separate accounts/projects or a separate backend, and apply defense in depth via RBAC and policy.
Can I embed ${terraform.workspace} in the backend key?
Not recommended. The backend block does not support expression interpolation. Most backends automatically namespace non-default workspaces (e.g., env:/<workspace>/...). Assume the design will split state per workspace and keep the key itself fixed.
I cannot delete a workspace. What should I do?
The default workspace cannot be deleted. Other workspaces cannot be deleted while their state still tracks managed resources. Select a different workspace, remove unwanted resources with terraform destroy or terraform state rm, then run terraform workspace delete once the state is empty.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
HCL Syntax: Terraform's Configuration Language (2026)
HCL2 fundamentals for Terraform — blocks, attributes, expres...
Terraform Authoring & Operations Pro: Complete Guide (2026)
Tactics for the Terraform Pro exam — module authoring, works...
Terraform Providers: Plugin Management Fundamentals (2026)
Provider mechanics — required_providers, versions, mirrors, ...
Terraform Resource Blocks: Declarative Infra Units (2026)
Resource block fundamentals — addresses, references, common ...
Terraform Data Sources: Read-Only External Data (2026)
Data source basics — declaration, refresh behavior, dependen...