Migrating from Terraform Workspaces
Terraform workspaces solve a simple problem: deploy the same code to multiple environments using one state backend. Atmos can adopt that workspace-backed state while moving environment configuration into explicit stack files.
How Workspaces Fit With Atmos
Workspaces are a valid way to organize Terraform state. When migrating to Atmos, the important shift is making configuration explicit in stacks while preserving the state layout that already works for your team.
1. Shared Backend Configuration
Terraform workspaces share backend configuration and differentiate state by workspace name. Atmos can keep that model, or configure separate backends per stack when a team explicitly wants that operating model.
# All workspaces use this backend configuration
terraform {
backend "s3" {
bucket = "my-terraform-state" # Same bucket for dev, staging, prod
key = "terraform.tfstate" # Workspace adds the environment-specific path
region = "us-east-1"
}
}
If your team wants independent backend configuration per environment, use the optional separate-backend migration path below.
2. Configuration Often Lives in Code
Workspace-based repos often put environment-specific choices in Terraform expressions. Atmos moves those choices into stack YAML:
3. Hidden State
Which workspaces exist? What resources do they contain? You have to inspect the state backend or track it manually.
$ terraform workspace list
default
dev
staging
prod
old-test-workspace # Is this safe to delete?
johns-experiment # What is this?
4. Component Versioning
Workspaces usually run the same root module version for every environment. Atmos stacks can point environments at different component versions when a rollout needs that control.
5. Optional Backend Changes
Teams that want separate backend configuration can migrate workspaces into per-stack backends. This is optional and should be planned carefully because it moves state.
How Atmos Helps
Atmos separates code (Terraform components) from configuration (stack YAML files). This gives you:
Atmos Advantages
- Workspace-compatible state - Keep existing workspace-backed state, or choose separate backend configuration
- Environment-specific config - No giant case statements
- Visible configuration - Stacks are files you can search, version, review
- Component reuse - Share code, customize config via inheritance
- Optional backend changes - Move state backends only when your team chooses that model
Migration Strategy
Before: Workspace-Based Setup
Deploy:
terraform workspace select prod
terraform apply # Which VPC am I deploying? Not obvious!
After: Atmos Stacks
Step 1: Create reusable component (generic code)
Step 2: Create environment-specific stacks (config)
Deploy:
atmos terraform apply vpc -s prod # Crystal clear: VPC in prod
atmos terraform apply vpc -s dev # VPC in dev
No workspace selection. No hidden state. Just explicit, declarative configuration.
Learn more: atmos terraform apply | atmos terraform plan
Step-by-Step Migration
1. Extract Workspace Logic
Identify all workspace-specific logic in your Terraform code:
Before:
locals {
instance_type = terraform.workspace == "prod" ? "m5.large" : "t3.small"
enable_monitoring = terraform.workspace == "prod" ? true : false
backup_retention = terraform.workspace == "prod" ? 30 : 7
}
After (convert to variables):
2. Create Stack Configurations
For each workspace, create a stack file:
3. Choose a State Backend Strategy
Atmos can use your existing workspace-backed state. Moving state to separate backends is optional and requires careful planning to avoid state loss.
Option A: Keep Workspace State (Easiest)
You can keep using workspace-based state with Atmos:
This lets you migrate incrementally without touching state.
Option B: Move to Separate Backends (Optional)
If your team explicitly wants independent backend configuration per environment, migrate each workspace to its own backend:
-
Export state from workspace:
terraform workspace select prodterraform state pull > prod.tfstate -
Configure new backend:
stacks/prod.yaml -
Initialize and push state:
atmos terraform init vpc -s prodterraform state push prod.tfstate -
Verify:
atmos terraform plan vpc -s prod # Should show no changes
4. Remove Workspace Logic
Clean up your Terraform code:
Remove:
# DELETE workspace references
locals {
env = terraform.workspace # Remove
}
# DELETE workspace conditionals
count = terraform.workspace == "prod" ? 1 : 0 # Remove
Replace with variables:
variable "environment" {
description = "Environment name"
type = string
}
variable "create_feature" {
description = "Whether to create optional feature"
type = bool
default = false
}
5. Update CI/CD
Before:
# Old CI/CD
terraform workspace select $ENV
terraform plan
terraform apply -auto-approve
After:
# New CI/CD
atmos terraform plan $COMPONENT -s $STACK
atmos terraform apply $COMPONENT -s $STACK -auto-approve
GitHub Actions example:
- name: Deploy VPC
run: |
atmos terraform apply vpc -s ${{ matrix.stack }}
strategy:
matrix:
stack: [dev, staging, prod]
Handling Common Patterns
Pattern 1: Workspace-Specific Resources
Before:
resource "aws_instance" "monitoring" {
count = terraform.workspace == "prod" ? 1 : 0
# ...
}
After:
Pattern 2: Workspace in Tags
Before:
tags = {
Environment = terraform.workspace
}
After:
Pattern 3: Workspace-Specific Data Sources
Before:
data "aws_ami" "app" {
most_recent = true
filter {
name = "name"
values = [terraform.workspace == "prod" ? "prod-ami-*" : "dev-ami-*"]
}
}
After:
Migration Checklist
- Audit all
terraform.workspacereferences in code - Convert workspace conditionals to variables
- Create Atmos
atmos.yamlconfiguration - Create stack files for each workspace
- Keep workspace-backed state, unless your team explicitly chooses separate backends
- If moving state, test the migration in dev first
- Verify
atmos terraform planshows no changes - Update CI/CD pipelines
- Update team documentation
- Update workspace commands to stack-based Atmos commands where appropriate
Benefits After Migration
- Explicit configuration - Environment settings live in stack files
- Workspace-compatible state - Keep existing workspace-backed state
- Environment-specific settings - No complex conditionals
- Better code review - Stack changes visible in YAML diffs
- Reusable components - Same code, different configs
- Easier testing - Deploy different component versions per stack
Common Questions
Get Help
Migrating from workspaces? We're here to help:
- Slack Community - Ask migration questions
- Office Hours - Live support for complex migrations
- GitHub Discussions - Share your migration story
Next Steps
Ready to get started?
- Quick Start - Build your first Atmos stack
- Core Concepts - Understand Atmos fundamentals
- Stack Configuration - Advanced YAML features