Managing Multi-Environment Deployments
1. Using Workspaces for Environments
Terraform workspaces allow you to manage multiple deployments of the same infrastructure configuration in different environments (e.g., dev, staging, prod) using a single Terraform configuration.
| Workspace | Description | Usage |
|---|---|---|
| default | The default workspace, used when no workspace is explicitly selected. | Automatically created and used if none specified. |
| dev | A development environment workspace. | Used for testing and development purposes. |
| prod | A production environment workspace. | Used for deploying infrastructure in a live environment. |
Example: Creating and Switching Workspaces
terraform workspace new dev
terraform workspace new prod
terraform workspace select dev
Note: Workspaces store state separately, so each environment maintains its own infrastructure state.
Warning: Be cautious when switching between workspaces, as operations on one workspace do not affect others.
2. Using Separate Directories
Example: Directory Structure
terraform/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── staging/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── prod/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── modules/
└── web-app/
├── main.tf
├── variables.tf
└── outputs.tf
| Directory | Description | Usage |
|---|---|---|
| environments/dev | Development environment configuration | Used for local testing and development |
| environments/staging | Staging environment configuration | Used for pre-production testing |
| environments/prod | Production environment configuration | Used for live deployment |
| modules/web-app | Reusable module for web application | Shared across environments |
Note: Each environment directory contains its own
terraform.tfvars file to manage environment-specific variables.Warning: Ensure that sensitive data is not committed to version control by using
terraform.tfvars files or environment variables.Best Practices
- Use separate directories for each environment to maintain isolation.
- Keep shared modules in a
modulesdirectory to avoid duplication. - Use environment-specific variable files for configuration management.
3. Using Variable Files per Environment
| Variable File | Usage | Description |
|---|---|---|
| terraform.tfvars | terraform apply |
Default variable file for all environments |
| terraform.tfvars.json | terraform apply |
JSON format for variables, same scope as terraform.tfvars |
| env.tfvars | terraform apply -var-file=env.tfvars |
Environment-specific variable file (e.g., dev.tfvars, prod.tfvars) |
Example: Environment-specific variables
# dev.tfvars
instance_type = "t3.micro"
ami_id = "ami-12345678"
Note: Variable files are loaded in order of precedence, with
-var-file overriding default files.
4. Using Remote State per Environment
| Property | Description | Example |
|---|---|---|
| backend | Defines the backend configuration for state storage | "s3" |
| bucket | Name of the S3 bucket to store state files | "my-terraform-state-bucket" |
| key | Path within the bucket for state files | "prod/terraform.tfstate" |
| region | AWS region where the bucket is located | "us-west-2" |
Example: S3 Backend Configuration
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "us-west-2"
}
}
Note: Ensure proper IAM permissions are set for the S3 bucket to allow Terraform to read/write state files.
Example: Environment-Specific State Keys
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "${var.environment}/terraform.tfstate"
region = "us-west-2"
}
}
5. Implementing Environment-Specific Resources
| Resource Type | Environment-Specific Configuration | Description |
|---|---|---|
| aws_instance | tags = { environment = var.environment } |
Tags instances with environment to differentiate them in AWS console and billing |
| aws_s3_bucket | bucket = "${var.environment}-myapp-bucket" |
Creates unique S3 buckets per environment to isolate data |
| google_compute_instance | name = "${var.environment}-instance" |
Names GCP compute instances uniquely per environment |
Example: Environment-specific S3 Bucket
resource "aws_s3_bucket" "app_bucket" {
bucket = "${var.environment}-myapp-bucket"
tags = {
environment = var.environment
}
}
Example: Environment-specific EC2 Instance
resource "aws_instance" "web_server" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
environment = var.environment
name = "web-server-${var.environment}"
}
}
6. Using Modules for Shared Code
| Property | Description | Example |
|---|---|---|
| source | Location of the module, can be local path or remote URL | source = "./modules/web-server" |
| version | Version constraint for the module (optional) | version = "~> 1.0" |
Example: Using a Module
module "web_server" {
source = "./modules/web-server"
instance_type = "t3.micro"
ami_id = "ami-12345678"
}
Note: Modules help reduce duplication and promote reusability across environments.
Module Best Practices
- Use versioned modules for stability
- Organize modules in a
modules/directory - Pass inputs to modules for customization
- Use outputs from modules to expose resources
7. Managing Environment Variables
| Variable | Type | Description | Usage |
|---|---|---|---|
| TF_VAR_env | string |
Environment identifier (e.g., dev, staging, prod) | Used to select appropriate configuration values |
| TF_VAR_region | string |
Cloud region for resource deployment | Set per environment to ensure proper resource placement |
| TF_VAR_vpc_id | string |
VPC ID for network configuration | Different per environment to isolate resources |
Example: Setting Environment Variables
export TF_VAR_env=prod
export TF_VAR_region=us-west-2
export TF_VAR_vpc_id=vpc-12345678
Note: Environment variables prefixed with
TF_VAR_ are automatically loaded by Terraform.
Example: Using Variables in Configuration
{"variable": {
"environment": {
"type": "string",
"description": "Deployment environment"
}
}}
8. Using Terraform Cloud Workspaces
| Property | Description | Example |
|---|---|---|
| workspace.name | Name of the workspace | "prod-us-east" |
| workspace.terraform_version | Terraform version to use for the workspace | "1.9.5" |
| workspace.vcs_repo | Version Control System repository configuration | { identifier = "myorg/myrepo" } |
| workspace.auto_apply | Whether to auto-apply changes | true |
Example: Creating a Workspace
resource "terraform_workspace" "prod" {
name = "prod-us-east"
terraform_version = "1.9.5"
auto_apply = true
vcs_repo {
identifier = "myorg/myrepo"
branch = "main"
}
}
Note: Workspaces in Terraform Cloud support isolation of state and configuration, enabling multi-environment deployments.
Warning: Ensure that sensitive variables are not exposed in the workspace configuration.
Key Features of Workspaces
- Isolation of state and configuration per environment
- Version Control Integration with Git repositories
- Auto Apply to automate deployments
- Variable Management for environment-specific values
9. Implementing Promotion Workflows
Example: Promotion Workflow with Environment Variables
export TF_VAR_environment=staging
terraform apply -var-file=staging.tfvars
| Workflow Step | Description | Action | Notes |
|---|---|---|---|
| 1. Staging Deployment | Deploy to staging environment | terraform apply -var-file=staging.tfvars |
Validate infrastructure before production |
| 2. Testing | Run tests on staging | terraform plan -var-file=staging.tfvars |
Ensure no unexpected changes |
| 3. Promotion | Apply to production | terraform apply -var-file=prod.tfvars |
Use same configuration but different variables |
Key Considerations
- Use
-var-fileto manage environment-specific configurations - Implement version control for state files to prevent drift
- Automate promotion steps using CI/CD pipelines
Warning: Never manually modify state files in production. Always use
terraform apply with proper variable files.
10. Using GitOps for Environments
Example: GitOps Workflow with Terraform
git clone https://github.com/example/terraform-environments.git
cd terraform-environments
terraform init -backend-config=envs/prod/backend.tfvars
terraform plan -var-file=envs/prod/variables.tfvars
terraform apply -var-file=envs/prod/variables.tfvars
| Component | Description | Usage |
|---|---|---|
| Terraform | Infrastructure as Code tool | Manages environment configurations |
| Git Repository | Source of truth for configurations | Stores environment-specific files |
| CI/CD Pipeline | Automated deployment process | Triggers Terraform apply on changes |
GitOps Benefits
- Version-controlled infrastructure
- Reproducible deployments
- Automated environment management
- Improved collaboration and auditability
Note: GitOps practices ensure that all environment changes are tracked and reviewed through version control.
Warning: Ensure proper access controls and secrets management in Git repositories containing sensitive configurations.