Terraform_workspaces_advanced
Terraform Workspaces Deep Dive
Section titled “Terraform Workspaces Deep Dive”Overview
Section titled “Overview”Terraform workspaces allow you to manage multiple environments (dev, staging, prod) with a single configuration. This guide covers advanced workspace patterns and best practices.
Workspace Basics
Section titled “Workspace Basics”┌─────────────────────────────────────────────────────────────────┐│ Terraform Workspaces ││ ││ ┌──────────────────────────────────────────────────────────┐ ││ │ terraform.tfstate.d │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ││ │ │ default/ │ │ dev/ │ │ prod/ │ │ ││ │ │ (local) │ │ (remote) │ │ (remote) │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────┘ │ ││ └──────────────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────────────┘Basic Workspace Commands
Section titled “Basic Workspace Commands”# List workspacesterraform workspace list
# Create workspaceterraform workspace new dev
# Select workspaceterraform workspace select dev
# Show current workspaceterraform workspace show
# Delete workspaceterraform workspace delete devWorkspace Configuration
Section titled “Workspace Configuration”Local Backend with Workspaces
Section titled “Local Backend with Workspaces”terraform { backend "local" { # Workspaces stored locally }}
# Access workspace name in configlocals { environment = terraform.workspace}Remote Backend with Workspaces
Section titled “Remote Backend with Workspaces”terraform { backend "s3" { bucket = "terraform-state-bucket" key = "terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks"
# Workspace-specific keys workspace_key_prefix = "workspaces" }}Using Workspaces in Configuration
Section titled “Using Workspaces in Configuration”Environment-Specific Values
Section titled “Environment-Specific Values”locals { # Different values per workspace instance_type = terraform.workspace == "prod" ? "t3.medium" : "t3.micro"
# Environment map environment_config = { dev = { instance_count = 1 enable_monitoring = false } staging = { instance_count = 2 enable_monitoring = true } prod = { instance_count = 5 enable_monitoring = true enable_backup = true } }
# Select config based on workspace config = local.environment_config[terraform.workspace]}
resource "aws_instance" "example" { instance_type = local.instance_type count = local.config.instance_count
tags = { Environment = terraform.workspace }}Workspace-Based Resource Creation
Section titled “Workspace-Based Resource Creation”# Only create certain resources in specific workspacesresource "aws_instance" "prod_only" { count = terraform.workspace == "prod" ? 1 : 0
instance_type = "r5.2xlarge"
tags = { Environment = "prod" }}
resource "aws_db_instance" "database" { # Create only in non-default workspaces count = terraform.workspace != "default" ? 1 : 0
identifier = "myapp-${terraform.workspace}"
tags = { Environment = terraform.workspace }}Multiple Workspaces Pattern
Section titled “Multiple Workspaces Pattern”Development Environment
Section titled “Development Environment”environment = "dev"instance_type = "t3.micro"instance_count = 1enable_monitoring = false
tags = { Environment = "dev" CostCenter = "dev"}Production Environment
Section titled “Production Environment”environment = "prod"instance_type = "t3.medium"instance_count = 5enable_monitoring = true
tags = { Environment = "prod" CostCenter = "production"}Variable File
Section titled “Variable File”variable "environment" { description = "Environment name" type = string}
variable "instance_type" { description = "EC2 instance type" type = string}
variable "instance_count" { description = "Number of instances" type = number}
variable "enable_monitoring" { description = "Enable CloudWatch monitoring" type = bool default = false}
variable "tags" { description = "Tags to apply to resources" type = map(string)}Workspace-Specific Backends
Section titled “Workspace-Specific Backends”# Use different backends per workspaceterraform { backend "s3" { bucket = "terraform-state-${terraform.workspace}" key = "terraform.tfstate" region = "us-east-1" }}Or use conditional configuration:
terraform { # Dynamic backend based on workspace backend "s3" {}}
# backend.hcl (per workspace)# dev.hclbucket = "terraform-state-dev"key = "dev/terraform.tfstate"
# prod.hclbucket = "terraform-state-prod"key = "prod/terraform.tfstate"Workspace Best Practices
Section titled “Workspace Best Practices”1. Use Remote Backend
Section titled “1. Use Remote Backend”# Always use remote backend for workspacesterraform { backend "s3" { bucket = "company-terraform-state" dynamodb_table = "terraform-locks" region = "us-east-1" }}2. Use Consistent Naming
Section titled “2. Use Consistent Naming”# Standard workspace namesterraform workspace new devterraform workspace new stagingterraform workspace new uatterraform workspace new prod3. Use Variables Files
Section titled “3. Use Variables Files”# Apply with workspace-specific variablesterraform workspace select devterraform apply -var-file="environments/dev.tfvars"
terraform workspace select prodterraform apply -var-file="environments/prod.tfvars"4. Tag Resources Consistently
Section titled “4. Tag Resources Consistently”locals { common_tags = { Environment = terraform.workspace ManagedBy = "Terraform" Project = var.project_name }}
resource "aws_instance" "example" { # ... tags = local.common_tags}CI/CD with Workspaces
Section titled “CI/CD with Workspaces”GitHub Actions
Section titled “GitHub Actions”name: Terraform
on: push: branches: [main] pull_request:
jobs: terraform: runs-on: ubuntu-latest strategy: matrix: workspace: [dev, staging, prod] steps: - uses: actions/checkout@v3
- name: Setup Terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.5.0
- name: Terraform Init run: | terraform workspace select ${{ matrix.workspace }} || terraform workspace new ${{ matrix.workspace }} terraform init env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Plan run: | terraform plan -var-file="environments/${{ matrix.workspace }}.tfvars" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Apply if: github.ref == 'refs/heads/main' run: | terraform apply -var-file="environments/${{ matrix.workspace }}.tfvars" -auto-approve env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}Workspace vs Directory
Section titled “Workspace vs Directory”When to Use Workspaces
Section titled “When to Use Workspaces”- Similar infrastructure across environments
- Same modules with different parameters
- State isolation needed
- Team shares same state backend
When to Use Directories
Section titled “When to Use Directories”- Different infrastructure per environment
- Different providers per environment
- Complete isolation required
- Different team ownership
Hybrid Approach
Section titled “Hybrid Approach”├── environments/│ ├── dev/│ │ ├── main.tf│ │ └── terraform.tfvars│ ├── staging/│ │ └── ...│ └── prod/│ └── ...└── modules/ └── ...Advanced Patterns
Section titled “Advanced Patterns”Workspace Outputs
Section titled “Workspace Outputs”# Get output from specific workspaceterraform workspace select prodterraform output
# JSON outputterraform output -json > outputs.jsonWorkspace State Operations
Section titled “Workspace State Operations”# Show stateterraform state show aws_instance.example
# Move stateterraform state mv aws_instance.example module.example.aws_instance.example
# Pull/push stateterraform state pull > backup.tfstateterraform state push backup.tfstateWorkspace Imports
Section titled “Workspace Imports”# Import into specific workspaceterraform workspace select prodterraform import aws_instance.example i-1234567890abcdef0Summary
Section titled “Summary”Terraform workspaces enable:
- Multi-environment management: Dev, staging, prod
- State isolation: Separate state per environment
- Configuration reuse: Single config, multiple environments
- CI/CD integration: Automated deployments
Best practices:
- Use remote backends for state safety
- Use variable files per workspace
- Tag resources with workspace name
- Use consistent workspace naming
- Consider directory-based approach for complete isolation