Q: How do you accommodate environment-specific variations, such as different EC2 instance sizes/types, across multiple environments in Terraform?
Architectural design for managing environment-specific configurations (such as different EC2 instance types and replica counts) across dev, staging, and production using clean Terraform patterns.
Want to master this scenario in a live sandbox? KodeKloud's HashiCorp Certified Terraform Associate (003) Interactive Labs covers this exact problem with hands-on terminal drills.
🛠️ Production Runbook & Step-by-Step Resolution
Pattern 1: Environment-Specific .tfvars Files with Directory Isolation
Structure the repository with reusable modules, invoking them with dedicated backend state and variable files per environment: `envs/dev/terraform.tfvars`, `envs/staging/terraform.tfvars`, `envs/prod/terraform.tfvars`.
# envs/dev/terraform.tfvars
instance_type = "t3.medium"
min_replicas = 2
max_replicas = 4
enable_ha = false
# envs/prod/terraform.tfvars
instance_type = "c6i.2xlarge"
min_replicas = 10
max_replicas = 50
enable_ha = true
Pattern 2: Terraform Map Lookups Based on Environment Workspace/Variable
Define a structured map within the module using the environment name as the lookup key. This enforces centralized governance over permitted SKUs.
variable "environment" {
type = string
default = "dev"
}
locals {
instance_type_map = {
dev = "t3.medium"
staging = "m5.large"
prod = "c6i.2xlarge"
}
instance_type = lookup(local.instance_type_map, var.environment, "t3.medium")
}
Pattern 3: DRY Orchestration with Terragrunt
Use **Terragrunt** to keep Terraform configurations 100% DRY. Define module sources once and pass environment-specific inputs via `env.hcl` files.
# terragrunt.hcl in /live/prod/compute
include "root" { path = find_in_parent_folders() }
terraform { source = "git::git@github.com:org/tf-modules.git//compute?ref=v2.1.0" }
inputs = {
instance_type = "c6i.2xlarge"
node_count = 20
}
Validation & Guardrails via HCL Validation Blocks
Add Terraform variable validation blocks to prevent developers from provisioning expensive production instance types in development environments.
- Use a single reusable Terraform module referenced across all environments to avoid duplicate code.
- Inject instance sizes and capacities via environment-specific .tfvars files or local lookup maps.
- Adopt Terragrunt to manage multi-account inputs with zero code duplication.
- Enforce variable validation rules to prevent oversized instances from being deployed in dev environments.