In this guide, you’ll learn how to create, select, and manage OpenTofu workspaces to maintain separate state files for multiple deployments of the same configuration. By the end, you’ll deploy a payroll application across three regions—US, UK, and India—using a single Terraform-compatible codebase.
Prerequisites
OpenTofu CLI installed and available in your PATH.
A sample project directory named project-sapphire.
Access to an S3-like backend (e.g., LocalStack) for state storage.
1. List the Default Workspace
Navigate to your project directory and list available workspaces. By default, OpenTofu starts with the default workspace.
cd ~/opentofu-projects/project-sapphire/
tofu workspace list
Expected output:
2. Create New Workspaces
Isolate state per region by creating three workspaces: us-payroll, uk-payroll, and india-payroll.
tofu workspace new us-payroll
tofu workspace new uk-payroll
tofu workspace new india-payroll
Verify:
Workspace Description default Default environment us-payroll State for US payroll deployment uk-payroll State for UK payroll deployment india-payroll State for India payroll deployment
3. Select a Workspace
Switch to the us-payroll workspace before running any commands:
tofu workspace select us-payroll
# Switched to workspace "us-payroll".
4. Understand Workspace State Location
OpenTofu stores each workspace’s state under terraform.tfstate.d/<workspace-name>. For example:
terraform.tfstate.d/india-payroll/terraform.tfstate
Do not manually edit files in the terraform.tfstate.d/ directory—always use OpenTofu commands to manage state.
5. Review the Configuration Files
Your project-sapphire folder should include:
variables.tf
variable "region" {
type = map ( string )
default = {
"us-payroll" = "us-east-1"
"uk-payroll" = "eu-west-2"
"india-payroll" = "ap-south-1"
}
}
variable "ami" {
type = map ( string )
default = {
"us-payroll" = "ami-24e140119877avm"
"uk-payroll" = "ami-351e40119877avm"
"india-payroll" = "ami-55140119877avm"
}
}
Quiz:
Type of region? A map(string).
region["india-payroll"] default? "ap-south-1".
ami["india-payroll"] default? "ami-55140119877avm".
provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.38.0"
}
}
}
provider "aws" {
region = lookup (var . region , terraform . workspace )
skip_credentials_validation = true
skip_requesting_account_id = true
s3_use_path_style = true
endpoints {
ec2 = "http://aws:4566"
dynamodb = "http://aws:4566"
s3 = "http://aws:4566"
}
}
6. Update main.tf to Invoke the Module
Add a module block in main.tf that points to your shared payroll application:
module "payroll_app" {
source = "/root/opentofu-projects/modules/payroll-app"
app_region = lookup (var . region , terraform . workspace )
ami = lookup (var . ami , terraform . workspace )
}
7. Initialize OpenTofu
Download providers and modules:
8. Apply Configuration Across All Workspaces
Deploy the payroll app in each region:
US Payroll
tofu workspace select us-payroll
tofu apply
# Enter "yes" to confirm
UK Payroll
tofu workspace select uk-payroll
tofu apply
# Enter "yes" to confirm
India Payroll
tofu workspace select india-payroll
tofu apply
# Enter "yes" to confirm
Workspace-State Mapping
Workspace AWS Region AMI ID State File Location us-payroll us-east-1 ami-24e140119877avm terraform.tfstate.d/us-payroll/terraform.tfstate uk-payroll eu-west-2 ami-351e40119877avm terraform.tfstate.d/uk-payroll/terraform.tfstate india-payroll ap-south-1 ami-55140119877avm terraform.tfstate.d/india-payroll/terraform.tfstate
References