Manage Terraform Workspaces Across Environments
A Terraform workspace management skill for multi-environment isolation, state backends, CI/CD deployment, and security patterns.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Automate and standardize your multi-environment infrastructure deployments using Terraform workspaces. Ensure consistent state management, environment-specific configurations, and robust CI/CD integration for reliable infrastructure as code.
Outcomes
What it gets done
Implement workspace isolation strategies for development, staging, and production.
Configure remote state backends with workspace-specific prefixes.
Manage environment-specific variables and resource naming conventions.
Integrate workspace management into CI/CD pipelines like GitHub Actions.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-terraform-workspace-manager | bash Overview
Terraform Workspace Manager
A Terraform skill for multi-environment workspace isolation - naming conventions, S3/DynamoDB remote state, environment-keyed variables, conditional resources, and a GitHub Actions CI/CD pipeline. Use when structuring a multi-environment Terraform project with workspace isolation; pair with separate cloud accounts and approval workflows for production, not workspace isolation alone.
What it does
This skill covers Terraform workspace management for multi-environment infrastructure - isolating dev, staging, and production deployments, configuring remote state backends, and organizing environment-specific variables. The core isolation strategy uses one workspace per environment with a <project>-<environment>-<region> naming convention, a separate state file per workspace, and explicit workspace selection in CI/CD rather than implicit switching. State is backed by an S3 backend with encryption, a DynamoDB lock table, and a workspace_key_prefix that scopes state paths per workspace. Environment-specific configuration is handled with a map(object({...})) variable keyed by terraform.workspace (instance type, min/max capacity, DB instance class per environment), read into a local.env_config alongside common tags that include the workspace name. Resources reference terraform.workspace directly for naming (e.g. "${terraform.workspace}-app-server") and for conditional creation - a CloudWatch dashboard is created with count = terraform.workspace == "dev" ? 0 : 1 so monitoring resources exist only in staging and prod. Cross-workspace references use a terraform_remote_state data source pointing at another workspace's state file, letting an app workspace pull subnet IDs or security group IDs from a shared-infrastructure workspace.
CI/CD integration is demonstrated with a GitHub Actions workflow using a matrix strategy over [dev, staging, prod], selecting or creating the matching workspace with terraform workspace select $ENV || terraform workspace new $ENV, planning against an environment-specific .tfvars file, and applying only on the main branch for non-prod environments (implying prod needs a separate, gated path). Recommended project layout separates environments/*.tfvars from modules/ and the root main.tf/variables.tf/outputs.tf/versions.tf. Troubleshooting commands cover listing, showing, creating, switching, and deleting workspaces, plus importing an existing cloud resource into a specific workspace; state migration between workspaces uses terraform state mv in the source workspace followed by terraform import in the target.
When to use - and when NOT to
Use this when structuring a Terraform project to manage multiple environments with workspace-based isolation, setting up a remote state backend with locking, wiring environment-aware variables and conditional resources, or building a CI/CD pipeline that deploys per environment through workspace selection.
Security guidance calls for workspace-specific IAM roles and policies, separate AWS accounts for production workspaces (not just a separate workspace within the same account), state file encryption and versioning, approval workflows gating production deployments, and auditing workspace changes through CloudTrail - all of which should be in place before relying on workspace isolation alone as a production safety boundary.
Inputs and outputs
Input is a set of environment-specific requirements (instance sizing, capacity, feature flags) and a target cloud backend for state storage. Output is Terraform configuration - backend blocks, environment-keyed variable maps, workspace-aware resource definitions, and a CI/CD workflow - plus a directory structure separating environment tfvars from reusable modules.
Integrations
Built on Terraform's native workspace feature with an AWS S3 + DynamoDB state backend (encryption, locking, versioning, KMS-backed server-side encryption) and GitHub Actions for CI/CD, using the hashicorp/setup-terraform action. Cross-workspace composition uses the terraform_remote_state data source to consume another workspace's outputs.
Who it's for
Infrastructure and platform engineers managing multiple environments (dev/staging/prod) with Terraform who need workspace isolation, a locked remote state backend, and a CI/CD pipeline that deploys the right environment safely.
### List all workspaces
terraform workspace list
### Show current workspace
terraform workspace show
### Create new workspace
terraform workspace new production-us-east-1
### Switch workspace safely
terraform workspace select staging
### Delete unused workspace (after moving resources)
terraform workspace delete old-environment
### Import existing resource into specific workspace
terraform workspace select prod
terraform import aws_instance.web i-1234567890abcdef0
Source README
Terraform Workspace Manager Expert
You are an expert in Terraform workspace management, specializing in multi-environment infrastructure deployments, remote state management, and workspace organization strategies. You understand the nuances of workspace isolation, state backend configurations, and deployment patterns across development, staging, and production environments.
Core Workspace Principles
Workspace Isolation Strategy
- Use workspaces for environment separation (dev, staging, prod)
- Implement consistent naming conventions:
<project>-<environment>-<region> - Maintain separate state files per workspace for complete isolation
- Avoid workspace switching in CI/CD pipelines - use explicit workspace selection
State Backend Configuration
terraform {
backend "s3" {
bucket = "terraform-state-bucket"
key = "infrastructure/terraform.tfstate"
region = "us-west-2"
encrypt = true
dynamodb_table = "terraform-locks"
# Workspace-specific state paths
workspace_key_prefix = "environments"
}
}
Workspace Management Best Practices
Environment-Specific Variable Management
### variables.tf
variable "environment_configs" {
type = map(object({
instance_type = string
min_capacity = number
max_capacity = number
db_instance_class = string
}))
default = {
dev = {
instance_type = "t3.micro"
min_capacity = 1
max_capacity = 2
db_instance_class = "db.t3.micro"
}
staging = {
instance_type = "t3.small"
min_capacity = 2
max_capacity = 4
db_instance_class = "db.t3.small"
}
prod = {
instance_type = "t3.medium"
min_capacity = 3
max_capacity = 10
db_instance_class = "db.t3.large"
}
}
}
locals {
env_config = var.environment_configs[terraform.workspace]
common_tags = {
Environment = terraform.workspace
Project = "my-app"
ManagedBy = "terraform"
}
}
Workspace-Aware Resource Naming
resource "aws_instance" "app_server" {
ami = data.aws_ami.ubuntu.id
instance_type = local.env_config.instance_type
tags = merge(local.common_tags, {
Name = "${terraform.workspace}-app-server"
})
}
resource "aws_s3_bucket" "app_data" {
bucket = "my-app-data-${terraform.workspace}-${random_id.bucket_suffix.hex}"
tags = local.common_tags
}
Advanced Workspace Patterns
Conditional Resource Creation
### Create monitoring resources only in staging and prod
resource "aws_cloudwatch_dashboard" "app_monitoring" {
count = terraform.workspace == "dev" ? 0 : 1
dashboard_name = "${terraform.workspace}-app-dashboard"
dashboard_body = jsonencode({
widgets = [
{
type = "metric"
properties = {
metrics = [
["AWS/EC2", "CPUUtilization", "InstanceId", aws_instance.app_server.id]
]
period = 300
stat = "Average"
region = "us-west-2"
title = "EC2 Instance CPU"
}
}
]
})
}
Cross-Workspace Data Sources
### Reference shared infrastructure from another workspace
data "terraform_remote_state" "shared_infra" {
backend = "s3"
config = {
bucket = "terraform-state-bucket"
key = "environments/shared/infrastructure/terraform.tfstate"
region = "us-west-2"
}
}
resource "aws_instance" "app_server" {
subnet_id = data.terraform_remote_state.shared_infra.outputs.private_subnet_ids[0]
vpc_security_group_ids = [data.terraform_remote_state.shared_infra.outputs.app_security_group_id]
}
CI/CD Integration Patterns
GitHub Actions Workspace Management
### .github/workflows/terraform.yml
name: Terraform Deployment
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
terraform:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [dev, staging, prod]
include:
- environment: dev
branch: develop
- environment: staging
branch: main
- environment: prod
branch: main
manual_approval: true
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.5.0
- name: Terraform Init
run: terraform init
- name: Select Workspace
run: |
terraform workspace select ${{ matrix.environment }} || \
terraform workspace new ${{ matrix.environment }}
- name: Terraform Plan
run: terraform plan -var-file="environments/${{ matrix.environment }}.tfvars"
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && matrix.environment != 'prod'
run: terraform apply -auto-approve -var-file="environments/${{ matrix.environment }}.tfvars"
Workspace Organization Strategies
Directory Structure
terraform/
├── environments/
│ ├── dev.tfvars
│ ├── staging.tfvars
│ └── prod.tfvars
├── modules/
│ ├── vpc/
│ ├── app/
│ └── database/
├── main.tf
├── variables.tf
├── outputs.tf
└── versions.tf
Environment-Specific tfvars
### environments/prod.tfvars
instance_count = 3
db_backup_retention = 30
enable_monitoring = true
log_level = "INFO"
### environments/dev.tfvars
instance_count = 1
db_backup_retention = 7
enable_monitoring = false
log_level = "DEBUG"
Troubleshooting and Maintenance
Workspace State Management
### List all workspaces
terraform workspace list
### Show current workspace
terraform workspace show
### Create new workspace
terraform workspace new production-us-east-1
### Switch workspace safely
terraform workspace select staging
### Delete unused workspace (after moving resources)
terraform workspace delete old-environment
### Import existing resource into specific workspace
terraform workspace select prod
terraform import aws_instance.web i-1234567890abcdef0
State Migration Between Workspaces
### Move resource between workspaces
terraform workspace select source-workspace
terraform state mv aws_instance.app aws_instance.app_old
terraform workspace select target-workspace
terraform import aws_instance.app i-1234567890abcdef0
Security and Compliance
Workspace Access Controls
- Implement workspace-specific IAM roles and policies
- Use separate AWS accounts for production workspaces
- Enable state file encryption and versioning
- Implement approval workflows for production deployments
- Audit workspace changes through CloudTrail integration
State File Protection
resource "aws_s3_bucket_versioning" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.terraform_state.arn
}
bucket_key_enabled = true
}
}
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.