Skip to content

thomasasamba-bot/Terraform-AWS-Multi-Region-Microservices-Platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌍 Terraform Multi-Region Microservices β€” AWS Active-Active

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

πŸ“ Architecture Overview

  • 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)         β”‚    β”‚    β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
              β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚    β”‚                              β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ—‚ Project Structure

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

βœ… Prerequisites

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.


πŸš€ Quick Start

1. Clone the repo

git clone https://github.com/<YOUR_USERNAME>/terraform-multiregion-microservices.git
cd terraform-multiregion-microservices

2. Bootstrap the Terraform state backend

This creates the S3 bucket and DynamoDB table required before terraform init:

chmod +x scripts/bootstrap-backend.sh
./scripts/bootstrap-backend.sh default my-project

Then update backend.tf with the bucket and table names printed by the script.

3. Configure your variables

cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars β€” set your domain_name, alarm_email, backend_image, etc.

4. Initialise, plan, and apply

terraform init
terraform validate
terraform plan -out=tfplan
terraform apply tfplan

βš™οΈ Module Reference

networking

Creates 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 β€”

frontend

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.

backend

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

database

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.

cache

ElastiCache Redis Replication Group with Multi-AZ failover, at-rest and in-transit encryption, and slow log delivery to CloudWatch.

security

  • 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

dns

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.

monitoring

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.


πŸ— Multi-Region Design Decisions

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

πŸ”’ Security Notes

  • 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

🧹 Tear Down

Use terraform destroy when not needed.

terraform destroy

Note: 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.


πŸ“„ License

MIT β€” free to use, fork, and adapt for your own projects.

About

Production-Grade 3-Tier Microservices Architecture on AWS using Terraform

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors