OpenTofu: A Beginners Guide to a Terraform Fork Including Migration From Terraform
OpenTofu Functions and Conditional Expressions
Demo OpenTofu Workspaces
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
Note
- 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:
* default
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:
tofu workspace list
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
Warning
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
- provider.tf
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
? Amap(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:
tofu init
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
Watch Video
Watch video content
Practice Lab
Practice lab