Skip to content

Terraform Workspaces and Environments: Multi-Environment Infrastructure

DodaTech 5 min read

Terraform workspaces and environment management strategies let you deploy the same infrastructure pattern across dev, staging, and production environments while keeping state completely isolated and configuration environment-aware.

What You'll Learn

In this tutorial, you will learn how to use Terraform workspaces for environment separation, implement workspace-aware configurations with conditional values, manage workspace state with remote backends, compare workspace strategy versus directory-based environments, and design multi-environment deployment pipelines.

Why It Matters

Every team needs to test infrastructure changes before production. Without environment isolation, a bad apply in dev can corrupt production resources. Workspaces and directory-based environments provide the isolation needed for safe, iterative infrastructure development.

Real-World Use

DodaTech manages three full environments for Durga Antivirus Pro using directory-based isolation with shared modules. Dev uses smaller instance sizes and single-AZ databases, staging mirrors production with reduced capacity, and production runs at full scale with Multi-AZ and encryption enabled.

Environment Strategy Comparison

graph TD
    subgraph "Workspace Strategy"
        W1[Single Configuration]
        W2[Workspace: dev]
        W3[Workspace: staging]
        W4[Workspace: prod]
        W1 --> W2
        W1 --> W3
        W1 --> W4
    end
    subgraph "Directory Strategy"
        D1[Root]
        D2[dev/main.tf]
        D3[staging/main.tf]
        D4[prod/main.tf]
        D5[modules/]
        D1 --> D2
        D1 --> D3
        D1 --> D4
        D1 --> D5
        D2 -.-> D5
        D3 -.-> D5
        D4 -.-> D5
    end
    style W2 fill:#50c878,color:#fff
    style W3 fill:#ff9900,color:#fff
    style W4 fill:#e74c3c,color:#fff
    style D2 fill:#50c878,color:#fff
    style D3 fill:#ff9900,color:#fff
    style D4 fill:#e74c3c,color:#fff
    style D5 fill:#4a90d9,color:#fff

Workspace-Based Environments

Creating and Managing Workspaces

# List existing workspaces
terraform workspace list

# Create environment workspaces
terraform workspace new dev
terraform workspace new staging
terraform workspace new production

# Switch to a workspace
terraform workspace select production

# Show current workspace
terraform workspace show

Expected output:

$ terraform workspace list
  default
  dev
* staging
  production

$ terraform workspace select production
Switched to workspace "production".

$ terraform workspace show
production

Workspace-Aware Configuration

# main.tf
locals {
  # Environment-specific configuration mapped by workspace
  env_config = {
    default = {
      instance_type  = "t2.micro"
      instance_count = 1
      db_multi_az    = false
      backup_days    = 1
    }
    dev = {
      instance_type  = "t2.micro"
      instance_count = 1
      db_multi_az    = false
      backup_days    = 3
    }
    staging = {
      instance_type  = "t3.small"
      instance_count = 2
      db_multi_az    = false
      backup_days    = 7
    }
    production = {
      instance_type  = "t3.large"
      instance_count = 5
      db_multi_az    = true
      backup_days    = 30
    }
  }

  config = local.env_config[terraform.workspace]
}

resource "aws_instance" "app" {
  count         = local.config.instance_count
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = local.config.instance_type

  tags = {
    Name        = "app-${terraform.workspace}-${count.index + 1}"
    Environment = terraform.workspace
  }
}

resource "aws_db_instance" "main" {
  engine         = "postgres"
  engine_version = "16.3"
  instance_class = local.config.instance_type == "t2.micro" ? "db.t4g.micro" : "db.r6g.large"
  multi_az       = local.config.db_multi_az

  backup_retention_period = local.config.backup_days
  deletion_protection     = terraform.workspace == "production"
}
terraform workspace select dev && terraform plan

Expected output:

Terraform will perform the following actions:

  # aws_instance.app[0] will be created
  + resource "aws_instance" "app" {
      + instance_type = "t2.micro"
      + tags          = { Name = "app-dev-1", Environment = "dev" }
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Workspace State in Remote Backends

terraform {
  backend "s3" {
    bucket         = "dodatech-terraform-state"
    key            = "infrastructure/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-locks"
  }
}

Expected state file paths in S3:

env:/dev/infrastructure/terraform.tfstate
env:/staging/infrastructure/terraform.tfstate
env:/production/infrastructure/terraform.tfstate

Directory-Based Environments

Environment Directory Structure

terraform/
  environments/
    dev/
      main.tf
      variables.tf
      backend.hcl
      terraform.tfvars
    staging/
      main.tf
      variables.tf
      backend.hcl
      terraform.tfvars
    production/
      main.tf
      variables.tf
      backend.hcl
      terraform.tfvars
  modules/
    vpc/
    ec2/
    rds/

Directory-Based Backend Per Environment

# environments/dev/backend.hcl
bucket = "dodatech-terraform-state"
key    = "dev/infrastructure/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"

# environments/production/backend.hcl
bucket = "dodatech-terraform-state"
key    = "production/infrastructure/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"

Environment-Specific Variable Files

# environments/dev/terraform.tfvars
environment    = "dev"
instance_type  = "t2.micro"
instance_count = 1
db_multi_az    = false
vpc_cidr       = "10.0.0.0/16"

# environments/production/terraform.tfvars
environment    = "production"
instance_type  = "t3.large"
instance_count = 5
db_multi_az    = true
vpc_cidr       = "10.2.0.0/16"
cd environments/production
terraform init -backend-config=backend.hcl
terraform plan -var-file=terraform.tfvars

When to Use Workspaces vs Directories

Criteria Workspaces Directories
State isolation Separate state per workspace Separate state per directory
Code duplication Single configuration Shared modules, separate root
Provider configs Shared across all Can differ per environment
Backend config Shared Can differ per environment
Approval workflows Same pipeline Separate per directory
Team size Small teams Large teams
Environment similarity Identical Different regions, providers

Common Mistakes

1. Accidentally Applying to Wrong Workspace

Running <a href="/devops/terraform/">terraform</a> apply in dev while thinking you are in production. Always verify with <a href="/devops/terraform/">terraform</a> workspace show before applying.

2. Not Backing Up Workspace State

Each workspace has its own state. A corrupted state in one workspace does not affect others, but you need per-workspace backups.

3. Using Workspace for Very Different Configs

If dev uses AWS and staging uses GCP, workspaces will not work. Use directory-based environments instead.

4. Hardcoding Environment Values

Writing conditional logic with hardcoded workspace names makes maintenance difficult. Use map variables keyed by workspace name.

5. Mixing Backend Types Across Workspaces

Workspaces require the same backend type. You cannot have one workspace on S3 and another on Terraform Cloud.

Practice Questions

1. What is the difference between workspace and directory-based environment isolation? Workspaces use a single configuration with separate state files. Directories use separate root modules with shared child modules.

2. How do you reference the current workspace name in a Terraform configuration? Using the <a href="/devops/terraform/">terraform</a>.workspace expression which returns the workspace name as a string.

3. When should you choose directories over workspaces for environment isolation? When environments need different provider configurations, backend configs, regions, or drastically different infrastructure.

4. Challenge: Create a multi-environment deployment using workspaces with a workspace-aware configuration that varies instance count, instance type, and database Multi-AZ setting based on the workspace.

Mini Project: Three-Environment Deployment

Create either a workspace-based or directory-based deployment for dev, staging, and production. Each environment should have different instance sizes, database configurations, and backup retention periods. Set up remote state with environment-isolated state files and a CI/CD pipeline that plans on PR and applies per environment.

Building Terraform Modules
Terraform Best Practices

What's Next

Implement Terraform workspaces or directory-based environments for your infrastructure, then study Best Practices for production-grade deployments. Explore DevOps workflows for multi-environment automation.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro