Project 04 ยท Architectural Projects

Two regions, both serving reads and writes, with DNS failover in under a minute when one goes dark.

Built withAWS CDK (TypeScript)
LevelAdvanced
Time to build1โ€“2 days
Running costPennies idle + ~$1 / health check

The problem

Single-region apps share one fate: when the region has a bad day, so do you. Most teams know multi-region is the answer but stop at “it’s too complex”. This project shows a clean, serverless pattern where every region is identical and independent, and the global layer is just data replication plus smart DNS.

What you’ll build

  • A DynamoDB global table replicated across two regions (multi-active, PITR on)
  • An identical HTTP API + Lambda stack per region, deployed from one CDK app
  • Optional custom domain with regional ACM certificates and API Gateway domain mappings
  • Route 53 latency records + HTTPS health checks every 10 seconds so unhealthy regions drop out automatically
  • A kill switch (SSM parameter) to rehearse a regional failure without breaking anything

Architecture

                        Route 53 (latency routing + health checks every 10s)
                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                 us-east-1                                   us-west-2
        HTTP API โ”€โ–ถ Lambda โ”€โ–ถ DynamoDB replica โ—€โ•โ• global table โ•โ•โ–ถ DynamoDB replica โ—€โ”€ Lambda โ—€โ”€ HTTP API

AWS services used

DynamoDB Global TablesAPI Gateway (HTTP)LambdaRoute 53ACMSystems Manager

How it works

  1. ReplicateWrites in either region replicate to the other in about a second through DynamoDB global tables.
  2. Serve locallyRoute 53 latency routing sends each user to the closest healthy region.
  3. DetectHealth checks hit /health, which verifies the in-region table and the kill switch.
  4. Fail overTwo failed checks (about 20 seconds) and Route 53 stops answering with that region. Traffic shifts on the next DNS lookup.

Key design decisions

  • Every region is self-sufficient: no cross-region calls on the request path.
  • Global tables use last-writer-wins, so writes use client-generated IDs and are idempotent.
  • The SSM kill switch makes failover drills boring, which is exactly what you want.

Deploy it

npm install
npx cdk bootstrap aws://ACCOUNT/us-east-1 aws://ACCOUNT/us-west-2

# Without a domain (regional URLs only)
npx cdk deploy --all

# With a domain you host in Route 53 (enables global URL + failover)
npx cdk deploy --all -c domainName=api.example.com -c zoneName=example.com -c hostedZoneId=Z123456ABCDEFG

Full prerequisites, parameters and clean-up steps are in the project README on the code page.

See it work

Flip /active-active/us-east-1/healthy to false and watch the x-served-by-region header switch to us-west-2 within about a minute. Writes made before the switch are already there.

Skills this demonstrates

Multi-region architectureGlobal data replicationDNS-based failoverRTO/RPO measurement

Get the code

Every file needed to build this project, written as a deployable AWS CDK app and validated with the CloudFormation schema.


Leave a Reply

Your email address will not be published. Required fields are marked *