Terraform Fundamentals - Workspaces
Learn how to use Terraform Workspaces to manage multiple environments like dev, staging, and production from a single codebase.
As Terraform projects begin to support multiple environments—like development, staging, and production—managing isolated infrastructure configurations becomes increasingly important. Up till now we have deployed all infrastructure using the default Terraform workspace. In real-world deployments—especially in red team operations where staging an environment before going live is essential—there is a need to separate environments cleanly. This is where Terraform Workspaces come into play.
A workspace in Terraform provides a separate instance of the state file. This means that each workspace gets its own copy of the state file. Through this Terraform keeps track of what has been created in that workspace, even though the underlying configuration files remain the same. Think of it like multiple deployments of the same infrastructure code, each tracked by its own state.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.
Terraform initializes every project with a default
workspace, but additional workspaces can be created and switched to as needed. This allows us to manage multiple environments from a single codebase, while keeping their respective resources and state isolated from each other.
The workflow for using workspaces starts with creating a new workspace using the terraform workspace new
command. For example:
terraform workspace new staging
This creates a new workspace named staging
and automatically switches to it. From this point forward, all operations—such as terraform plan
, apply
, and destroy
—will use a separate state file associated with the staging
workspace. To switch between workspaces, the following command is used:
terraform workspace select production
To list all available workspaces:
terraform workspace list
And to delete a workspace:
terraform workspace delete staging
It’s important to understand that workspaces only isolate the state. They do not automatically provide isolation of variables, backends, or resources unless the code is written with workspace awareness. For instance, if a variable like a resource name or tag includes the workspace name using the built-in terraform.workspace
value, it helps avoid naming collisions. Example:
resource "aws_s3_bucket" "op_bucket" {
bucket = "redteam-${terraform.workspace}-ops"
}
This dynamic naming ensures that redteam-staging-ops
and redteam-production-ops
buckets are created in different workspaces without conflict.
Here is the Terraform Hello World project updated to use Terraform workspaces.
There are also limitations and tradeoffs to using workspaces. For example, because all environments share the same codebase, it’s harder to version them independently or have environment-specific logic unless the configuration is explicitly written that way using conditionals or variable files. Furthermore, collaboration can become risky if multiple team members share the same working directory, such as on a shared server or CI runner. Since the selected workspace is stored locally in the .terraform
folder, switching workspaces in one session can unexpectedly affect others, leading to deployments or changes being applied in the wrong environment. Mistakes such as applying code in the wrong workspace can have real consequences—especially in red team infrastructure where uptime, OPSEC, and stealth are critical.
For these reasons, many teams choose to use directory-based environment separation or separate backends instead of—or in addition to—workspaces.
From a red team perspective, Terraform workspaces can be particularly helpful during infrastructure development. For instance, an operator might spin up a testing
environment to verify that a redirector configuration works as expected, then switch to production
to deploy the actual infrastructure that will be used in the field.
TL;DR
- Terraform workspaces allow to manage multiple isolated environments (like dev, staging, prod) using the same configuration code.
- Each workspace gets its own state file, enabling separate deployments without duplication.
- terraform.workspace variable can be used in resource names or tags, to dynamically adapt infrastructure across environments while keeping everything clean and isolated.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.