Terraform Advanced — Account-Per-Environment
Use separate AWS accounts for blast-radius isolation.
The Pattern
AWS Organization
├── Management Account (billing, org policies)
├── Security Account (CloudTrail, GuardDuty)
├── Shared Services (CI/CD, artifact repos)
├── Dev Account
├── Staging Account
└── Prod Account
Terraform with assume_role
# In CI/CD — assume into the target account
provider "aws" {
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::${var.target_account_id}:role/terraform-deploy"
}
}
Account Vending with Terraform
resource "aws_organizations_account" "dev" {
name = "dev"
email = "aws-dev@example.com"
parent_id = aws_organizations_organizational_unit.workloads.id
lifecycle {
prevent_destroy = true
}
}
# Baseline each account
module "account_baseline" {
source = "./modules/account-baseline"
account_id = aws_organizations_account.dev.id
# Sets up: CloudTrail, Config, GuardDuty, default VPC deletion
}
Benefits
✅ Blast radius: dev mistake can't affect prod
✅ Billing: clear cost attribution per environment
✅ Security: SCPs limit what each account can do
✅ Quotas: independent service limits per account
💡 Production Tip: Use AWS Service Control Policies (SCPs) to prevent dangerous actions in non-prod accounts, like creating expensive instance types.
What’s Next?
Deploy without downtime.