A production-grade Terraform project that deploys a 3-tier microservices application across two AWS regions in an active-active configuration using modular, reusable Terraform code.
It demostartes:
- Infrastructure as Code (IaC) with modular Terraform design
- Multi-region deployment strategy
- High availability and fault tolerance
- Cloudplaform using AWS
- Global routing with Route 53 latency-based routing and health checks (failover routing)
- Highly available frontend with CloudFront CDN and S3 static hosting
- Resilient backend with ECS Fargate, ALB, and auto-scaling
- Security with WAF, IAM, Security Groups
- Global database with Multi-region RDS (PostgreSQL)
- Distributed caching with ElastiCache Redis (Multi-AZ)
- State Management with and S3 + DynamoDB locking
ββββββββββββββββ βββββββββββββββββββββββ
β Route 53 (Global) β
β Latency-Based Routing + Health β
ββββββββββββββ¬βββββββββββββββ¬βββββββββββ
β β
βββββββββββββββββββββββββΌβββ ββββββββΌββββββββββββββββββββββββ
β us-east-1 (Primary) β β us-west-2 (Secondary) β
β β β β
β ββββββββββββββββββββ β β ββββββββββββββββββββ β
β β CloudFront CDN β β β β CloudFront CDN β β
β β (S3 Frontend) β β β β (S3 Frontend) β β
β ββββββββββ¬ββββββββββ β β ββββββββββ¬ββββββββββ β
β β β β β β
β ββββββββββΌββββββββββ β β ββββββββββΌββββββββββ β
β β WAF + ALB β β β β WAF + ALB β β
β ββββββββββ¬ββββββββββ β β ββββββββββ¬ββββββββββ β
β β β β β β
β ββββββββββΌββββββββββ β β ββββββββββΌββββββββββ β
β β ECS Fargate β β β β ECS Fargate β β
β β (Auto-scaling) β β β β (Auto-scaling) β β
β ββββββββββ¬ββββββββββ β β ββββββββββ¬ββββββββββ β
β β β β β β
β ββββββββββΌββββββββββ β β ββββββββββΌβββββββββ β β
β β ElastiCache β β β β ElastiCache β β
β β Redis (Multi-AZ)β β β β Redis (Multi-AZ) β β
β ββββββββββββββββββββ β β βββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββ β β ββββββββββββββββββββ β
β β PostgreSQL βββ-ββΌβββββΌββββββββΊβ PostgreSQL β β
β β β β β β (Read Replica) β β
β β (Writer) β β β ββββββββββββββββββββ β
β ββββββββββββββββββββ β β β
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
terraform-multiregion-microservices/
βββ main.tf # Root orchestration β wires all modules
βββ providers.tf # Multi-region AWS providers (primary, secondary, global)
βββ backend.tf # S3 + DynamoDB remote state
βββ variables.tf # All input variables with defaults
βββ outputs.tf # Key infrastructure outputs
βββ terraform.tfvars.example # Example variable values (copy β terraform.tfvars)
β
βββ modules/
β βββ networking/ # VPC, subnets, NAT GW, IGW, flow logs
β βββ frontend/ # S3 + CloudFront CDN with origin failover
β βββ backend/ # ECS Fargate + ALB + auto-scaling
β βββ database/ # PostgreSQL
β βββ cache/ # ElastiCache Redis (Multi-AZ replication group)
β βββ security/ # WAF v2 (regional + CloudFront), Secrets Manager
β βββ dns/ # Route 53 latency-based routing + health checks
β βββ monitoring/ # CloudWatch alarms, dashboards, SNS notifications
β
βββ scripts/
βββ bootstrap-backend.sh # Pre-creates S3 + DynamoDB for remote state
| Tool | Version |
|---|---|
| Terraform | >= 1.5.0 |
| AWS CLI | >= 2.x |
| AWS Account | Two regions enabled (us-east-1, us-west-2) |
AWS credentials must have sufficient IAM permissions to create VPCs, ECS, RDS, ElastiCache, CloudFront, Route 53, WAF, and related resources.
git clone https://github.com/<YOUR_USERNAME>/terraform-multiregion-microservices.git
cd terraform-multiregion-microservicesThis creates the S3 bucket and DynamoDB table required before terraform init:
chmod +x scripts/bootstrap-backend.sh
./scripts/bootstrap-backend.sh default my-projectThen update backend.tf with the bucket and table names printed by the script.
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars β set your domain_name, alarm_email, backend_image, etc.terraform init
terraform validate
terraform plan -out=tfplan
terraform apply tfplanCreates a full VPC per region with public, private, and database subnet tiers across all provided AZs. Includes NAT Gateways (one per AZ for high availability), route tables, and VPC Flow Logs to CloudWatch.
| Variable | Description | Default |
|---|---|---|
vpc_cidr |
VPC CIDR block | 10.0.0.0/16 |
availability_zones |
List of AZs | us-east-1 |
name_prefix |
Resource name prefix | β |
S3 static site bucket behind a CloudFront distribution. Supports origin failover between the primary and secondary ALB via a CloudFront Origin Group. WAF is attached at the CloudFront level.
ECS Fargate cluster with an Application Load Balancer. Includes:
- Circuit breaker with automatic rollback
- CPU and memory target-tracking auto-scaling (FARGATE + FARGATE_SPOT mix)
- ALB access log archival to S3
- WAF association
- Secrets Manager integration for DB credentials
PostgreSQL instances spanning both regions. The primary region hosts the writer instance; the secondary joins as a read replica. Uses manage_master_user_password for automated credential rotation.
ElastiCache Redis Replication Group with Multi-AZ failover, at-rest and in-transit encryption, and slow log delivery to CloudWatch.
- WAF v2 Regional on each ALB: Core Rule Set, Known Bad Inputs, SQLi rules, and IP-based rate limiting
- WAF v2 CloudFront on the CDN distribution (must be deployed to
us-east-1) - Secrets Manager secret for DB credentials with 30-day automatic rotation
Route 53 latency-based routing records pointing to each region's ALB. Includes HTTPS health checks β if a region fails its health check, Route 53 automatically stops routing traffic there.
CloudWatch alarms for ECS CPU/memory, ALB 5xx errors and p99 latency, PostgreSQL CPU and connections, and Redis CPU and evictions. All alarms notify via SNS β email. Includes a per-region CloudWatch Dashboard.
| Concern | Solution |
|---|---|
| Routing | Route 53 latency-based routing sends users to the closest healthy region |
| Failover | Route 53 health checks + ALB circuit breakers provide automatic failover |
| Database | PostgreSQL instance β single writer, replicated reader in secondary region |
| Frontend CDN | CloudFront Origin Group falls back to the secondary ALB on 5xx errors |
| State isolation | Single S3 backend with a shared key; modules are region-parameterised |
| Security | WAF at both ALB (regional) and CloudFront (global) layers |
| Observability | Independent CloudWatch dashboards and alarms per region |
- All S3 buckets have public access blocked
- PostgreSQL uses
manage_master_user_passwordβ no plaintext passwords in state - ECS tasks retrieve DB credentials from Secrets Manager at runtime
- Redis and PostgreSQL use in-transit and at-rest encryption
- VPC Flow Logs capture all traffic for audit purposes
- WAF blocks common OWASP threats and rate-limits per IP
Use terraform destroy when not needed.
terraform destroyNote: The PostgrSQL must have its secondary removed before the primary can be deleted. Terraform handles this automatically via
depends_on, but if you see errors, remove the secondary cluster manually first.
MIT β free to use, fork, and adapt for your own projects.