Multi-Region Deployment
Deploy across multiple AWS regions for high availability
π΅ Cost: Multi-region deployments approximately double your infrastructure costs. Consider your RTO/RPO requirements carefully. Pilot Light or Warm Standby can reduce costs while still providing regional redundancy.
Why Multi-Region?
- Disaster recovery - Survive complete region outages
- Lower latency - Serve users from nearest region
- Compliance - Data residency requirements
- Business continuity - Critical applications must stay online
Deployment Strategies
| Strategy | RTO | RPO | Cost | Complexity |
|---|---|---|---|---|
| Backup & Restore | Hours | Hours | Low | Low |
| Pilot Light | 10-30 min | Minutes | Low-Medium | Medium |
| Warm Standby | Minutes | Seconds | Medium-High | Medium |
| Active-Active | Seconds | Zero | High (2x) | High |
Start with Pilot Light
For most applications, Pilot Light provides a good balance of cost and recovery time. You can upgrade to Warm Standby or Active-Active as business requirements grow.
Plain Text
ACTIVE-ACTIVE MULTI-REGION ARCHITECTURE
βββββββββββββββββββ
β Route 53 β
β (Latency-Based β
β Routing) β
ββββββββββ¬βββββββββ
β
ββββββββββββββββββ΄βββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββ
β ap-southeast-1 β β us-east-1 β
β (Primary) β β (Secondary) β
βββββββββββββββββββββββ€ βββββββββββββββββββββββ€
β βββββββββββββββββ β β βββββββββββββββββ β
β β ALB β β β β ALB β β
β βββββββββ¬ββββββββ β β βββββββββ¬ββββββββ β
β β β β β β
β βββββββββΌββββββββ β β βββββββββΌββββββββ β
β β ECS Fargate β β β β ECS Fargate β β
β β (2-5 tasks) β β β β (2-5 tasks) β β
β βββββββββ¬ββββββββ β β βββββββββ¬ββββββββ β
β β β β β β
β βββββββββΌββββββββ β ββββββββΌβββββββββββΌββββββββ β
β β RDS Primary ββββΌββReplicationββΆβ RDS Replica β β
β β (Multi-AZ) β β β β (Read Replica)β β
β βββββββββββββββββ β β βββββββββββββββββ β
β β β β
β βββββββββββββββββ β ββββββββΌβββββββββββββββββββ β
β β S3 ββββΌβββCRRββββββΌββΆβ S3 β β
β βββββββββββββββββ β β βββββββββββββββββ β
βββββββββββββββββββββββ βββββββββββββββββββββββ
CRR = Cross-Region ReplicationProvider Configuration
HCL
# providers.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Primary region
provider "aws" {
region = "ap-southeast-1"
alias = "primary"
}
# Secondary region
provider "aws" {
region = "us-east-1"
alias = "secondary"
}ECR Cross-Region Replication
HCL
# Replicate container images to secondary region
resource "aws_ecr_replication_configuration" "main" {
provider = aws.primary
replication_configuration {
rule {
destination {
region = "us-east-1"
registry_id = data.aws_caller_identity.current.account_id
}
}
}
}RDS Cross-Region Read Replica
HCL
# Primary RDS instance (ap-southeast-1)
resource "aws_db_instance" "primary" {
provider = aws.primary
identifier = "myapp-db-primary"
engine = "postgres"
engine_version = "15.4"
instance_class = "db.t3.medium"
allocated_storage = 100
storage_encrypted = true
multi_az = true
backup_retention_period = 7
# Enable automated backups (required for read replica)
backup_window = "03:00-04:00"
maintenance_window = "Mon:04:00-Mon:05:00"
tags = {
Name = "myapp-db-primary"
}
}
# Cross-region read replica (us-east-1)
resource "aws_db_instance" "replica" {
provider = aws.secondary
identifier = "myapp-db-replica"
instance_class = "db.t3.medium"
# Point to primary instance
replicate_source_db = aws_db_instance.primary.arn
# Replica-specific settings
backup_retention_period = 7
storage_encrypted = true
kms_key_id = aws_kms_key.secondary.arn
# Can be promoted to standalone in DR scenario
tags = {
Name = "myapp-db-replica"
}
}S3 Cross-Region Replication
HCL
# Primary bucket
resource "aws_s3_bucket" "primary" {
provider = aws.primary
bucket = "myapp-data-ap-southeast-1"
}
resource "aws_s3_bucket_versioning" "primary" {
provider = aws.primary
bucket = aws_s3_bucket.primary.id
versioning_configuration {
status = "Enabled"
}
}
# Secondary bucket
resource "aws_s3_bucket" "secondary" {
provider = aws.secondary
bucket = "myapp-data-us-east-1"
}
resource "aws_s3_bucket_versioning" "secondary" {
provider = aws.secondary
bucket = aws_s3_bucket.secondary.id
versioning_configuration {
status = "Enabled"
}
}
# Replication configuration
resource "aws_s3_bucket_replication_configuration" "primary_to_secondary" {
provider = aws.primary
bucket = aws_s3_bucket.primary.id
role = aws_iam_role.replication.arn
rule {
id = "replicate-all"
status = "Enabled"
destination {
bucket = aws_s3_bucket.secondary.arn
storage_class = "STANDARD"
}
}
}Latency-Based Routing
Route users to the closest region:
HCL
# Primary region record
resource "aws_route53_record" "primary" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
alias {
name = aws_lb.primary.dns_name
zone_id = aws_lb.primary.zone_id
evaluate_target_health = true
}
latency_routing_policy {
region = "ap-southeast-1"
}
set_identifier = "primary"
}
# Secondary region record
resource "aws_route53_record" "secondary" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
alias {
name = aws_lb.secondary.dns_name
zone_id = aws_lb.secondary.zone_id
evaluate_target_health = true
}
latency_routing_policy {
region = "us-east-1"
}
set_identifier = "secondary"
}Failover Routing
Automatic failover when primary is unhealthy:
HCL
# Health check for primary
resource "aws_route53_health_check" "primary" {
fqdn = aws_lb.primary.dns_name
port = 443
type = "HTTPS"
resource_path = "/api/health"
failure_threshold = 3
request_interval = 30
tags = {
Name = "primary-health-check"
}
}
# Primary record (with health check)
resource "aws_route53_record" "primary_failover" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
alias {
name = aws_lb.primary.dns_name
zone_id = aws_lb.primary.zone_id
evaluate_target_health = true
}
failover_routing_policy {
type = "PRIMARY"
}
set_identifier = "primary"
health_check_id = aws_route53_health_check.primary.id
}
# Secondary record (failover target)
resource "aws_route53_record" "secondary_failover" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
alias {
name = aws_lb.secondary.dns_name
zone_id = aws_lb.secondary.zone_id
evaluate_target_health = true
}
failover_routing_policy {
type = "SECONDARY"
}
set_identifier = "secondary"
}Recommended Region Pairs
| Primary | Secondary | Use Case |
|---|---|---|
| ap-southeast-1 (Singapore) | ap-northeast-1 (Tokyo) | Asia-Pacific focus |
| ap-southeast-1 (Singapore) | us-east-1 (N. Virginia) | Global, cost-optimized |
| us-east-1 (N. Virginia) | us-west-2 (Oregon) | US-focused |
| eu-west-1 (Ireland) | eu-central-1 (Frankfurt) | Europe-focused, GDPR |
Your Configuration
This project uses:
- Primary: ap-southeast-1 (Singapore)
- Secondary: us-east-1 (N. Virginia)