Description
Build a highly available, multi-region AWS infrastructure using Terraform with auto-scaling, load balancing, and disaster recovery.
Objective
Design and deliver a production-ready cloud solution with clear infrastructure, security, and operations practices.
Solution
Plan the architecture
- 1Define the workload, availability requirements, regions, and recovery objectives.
- 2Choose the network, compute, storage, and identity boundaries for the solution.
- 3
terraform
# provider.tf provider "aws" { region = var.primary_region alias = "primary" } provider "aws" { region = var.secondary_region alias = "secondary" } - 4
terraform
# VPCs module "vpc_primary" { source = "terraform-aws-modules/vpc/aws" providers = { aws = aws.primary } name = "primary-vpc" cidr = "10.0.0.0/16" azs = ["us-east-1a", "us-east-1b"] public_subnets = ["10.0.1.0/24", "10.0.2.0/24"] private_subnets = ["10.0.3.0/24", "10.0.4.0/24"] } module "vpc_secondary" { source = "terraform-aws-modules/vpc/aws" providers = { aws = aws.secondary } name = "secondary-vpc" cidr = "10.1.0.0/16" azs = ["us-west-2a", "us-west-2b"] public_subnets = ["10.1.1.0/24", "10.1.2.0/24"] private_subnets = ["10.1.3.0/24", "10.1.4.0/24"] }
Provision the foundation
- 1Configure AWS providers for multiple regions in Terraform.
- 2Create reusable modules for VPC, EC2, ALB, ASG, and RDS.
- 3Apply least-privilege IAM roles, tagging, and configuration conventions.
- 4
terraform
# Launch Template + Auto Scaling resource "aws_launch_template" "app" { name_prefix = "app-template" image_id = var.ami_id instance_type = "t3.micro" } resource "aws_autoscaling_group" "asg_primary" { provider = aws.primary desired_capacity = 2 max_size = 4 min_size = 2 vpc_zone_identifier = module.vpc_primary.private_subnets launch_template { id = aws_launch_template.app.id version = "$Latest" } tag { key = "Name" value = "primary-asg" propagate_at_launch = true } } - 5
terraform
# Load Balancer resource "aws_lb" "alb_primary" { provider = aws.primary name = "primary-alb" internal = false load_balancer_type = "application" subnets = module.vpc_primary.public_subnets } resource "aws_lb_target_group" "tg_primary" { provider = aws.primary name = "primary-tg" port = 80 protocol = "HTTP" vpc_id = module.vpc_primary.vpc_id } resource "aws_lb_listener" "listener_primary" { provider = aws.primary load_balancer_arn = aws_lb.alb_primary.arn port = 80 protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.tg_primary.arn } } - 6
terraform
# Route 53 Failover resource "aws_route53_record" "primary" { zone_id = var.zone_id name = "app.example.com" type = "A" set_identifier = "primary" failover_routing_policy { type = "PRIMARY" } alias { name = aws_lb.alb_primary.dns_name zone_id = aws_lb.alb_primary.zone_id evaluate_target_health = true } } resource "aws_route53_record" "secondary" { zone_id = var.zone_id name = "app.example.com" type = "A" set_identifier = "secondary" failover_routing_policy { type = "SECONDARY" } alias { name = aws_lb.alb_secondary.dns_name zone_id = aws_lb.alb_secondary.zone_id evaluate_target_health = true } } - 7
terraform
# Disaster Recovery (S3 + RDS) resource "aws_s3_bucket" "primary" { provider = aws.primary bucket = "primary-app-bucket" } resource "aws_s3_bucket_replication_configuration" "replication" { provider = aws.primary bucket = aws_s3_bucket.primary.id role = aws_iam_role.replication.arn rules { id = "replication" status = "Enabled" destination { bucket = aws_s3_bucket.secondary.arn storage_class = "STANDARD" } } } resource "aws_db_instance" "primary_rds" { provider = aws.primary engine = "mysql" instance_class = "db.t3.micro" allocated_storage = 20 name = "appdb" username = "admin" password = var.db_password } resource "aws_db_instance" "secondary_rds" { provider = aws.secondary replicate_source_db = aws_db_instance.primary_rds.arn } - 8
terraform
# Commands terraform init terraform validate terraform plan -var="primary_region=us-east-1" -var="secondary_region=us-west-2" -var="ami_id=ami-0abcd1234efgh5678" -var="zone_id=Z123456789" -var="db_password=SuperSecret123" terraform apply -auto-approve
Validate and operate
- 1Add Route 53 health checks for failover between regions.
- 2Enable CloudWatch metrics, logs, and alarms for ASG, ALB, and RDS.
- 3Document rollback, scaling, and disaster-recovery procedures.
- 4Test failover by simulating primary region outage and verifying secondary takeover.
Tool Stack Used
- βοΈAWS
- ποΈTerraform
- π§Route 53
- π§Auto Scaling
- π§Application Load Balancer
- π§S3 Replication
- π§RDS Read Replica
- πMonitoring