AWS — Three-Tier Web App in a VPC
Public / private / data subnets across two AZs: CloudFront and WAF at the edge, an ALB into an auto-scaled app tier, Aurora with a standby, and an async order path through SQS and Lambda.
Rendering…
Make it your own.
{
"nodes": [
{ "id": "regional", "type": "container", "label": "Regional services — reached through a VPC endpoint, no address in any subnet", "x": 20, "y": 826, "width": 560, "height": 160, "fill": "rgba(241,245,249,0.35)", "stroke": "#64748b" },
{ "id": "vpc", "type": "container", "label": "VPC 10.0.0.0/16 — eu-west-1", "x": 20, "y": 190, "width": 1180, "height": 620, "fill": "rgba(255,247,237,0.30)", "stroke": "#c2410c" },
{ "id": "pubsn","type": "container", "label": "Public subnets — 10.0.0.0/20 (az-a, az-b)", "x": 50, "y": 232, "width": 1120, "height": 158, "fill": "rgba(220,252,231,0.28)", "stroke": "#15803d" },
{ "id": "appsn","type": "container", "label": "Private app subnets — 10.0.16.0/20", "x": 50, "y": 420, "width": 1120, "height": 170, "fill": "rgba(219,234,254,0.28)", "stroke": "#1d4ed8" },
{ "id": "datsn","type": "container", "label": "Private data subnets — 10.0.32.0/20", "x": 50, "y": 620, "width": 1120, "height": 170, "fill": "rgba(237,233,254,0.28)", "stroke": "#6d28d9" },
{ "id": "users", "type": "user-group", "label": "Customers", "x": 40, "y": 30, "width": 130, "height": 104, "fill": "#e0f2fe", "stroke": "#0369a1" },
{ "id": "dns", "type": "cloud", "label": "Route 53 — shop.example.com", "x": 200, "y": 45, "width": 170, "height": 74, "fill": "#e0f2fe", "stroke": "#0369a1" },
{ "id": "cdn", "type": "aws-cloudfront", "label": "CloudFront", "x": 410, "y": 30, "width": 116, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "waf", "type": "shield-check", "label": "AWS WAF", "x": 566, "y": 33, "width": 120, "height": 104, "fill": "#fee2e2", "stroke": "#b91c1c" },
{ "id": "s3", "type": "aws-s3", "label": "S3 — assets", "x": 726, "y": 30, "width": 116, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "iam", "type": "aws-iam", "label": "IAM roles", "x": 882, "y": 30, "width": 116, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "igw", "type": "network-globe", "label": "Internet gateway", "x": 100, "y": 267, "width": 120, "height": 104, "fill": "#dcfce7", "stroke": "#15803d" },
{ "id": "alb", "type": "aws-elb", "label": "ALB :443", "x": 280, "y": 264, "width": 116, "height": 110, "fill": "#fff7ed", "stroke": "#f97316", "bold": true },
{ "id": "nat", "type": "router", "label": "NAT gateway", "x": 470, "y": 267, "width": 120, "height": 104, "fill": "#dcfce7", "stroke": "#15803d" },
{ "id": "bastion", "type": "lock", "label": "SSM session host", "x": 660, "y": 267, "width": 140, "height": 104, "fill": "#fee2e2", "stroke": "#b91c1c" },
{ "id": "ec2a", "type": "aws-ec2", "label": "EC2 ASG — az-a", "x": 100, "y": 458, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "ec2b", "type": "aws-ec2", "label": "EC2 ASG — az-b", "x": 280, "y": 458, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "ecs", "type": "docker-container", "label": "ECS Fargate — checkout", "x": 470, "y": 461, "width": 130, "height": 104, "fill": "#dbeafe", "stroke": "#1d4ed8" },
{ "id": "ordr", "type": "microservice", "label": "Orders service", "x": 660, "y": 461, "width": 130, "height": 104, "fill": "#dbeafe", "stroke": "#1d4ed8", "bold": true },
{ "id": "lam", "type": "aws-lambda", "label": "Lambda — invoices","x": 850, "y": 458, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "sqs", "type": "aws-sqs", "label": "SQS — order jobs", "x": 250, "y": 862, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "rdsp", "type": "aws-rds", "label": "Aurora writer", "x": 100, "y": 658, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "rdss", "type": "aws-rds", "label": "Aurora standby", "x": 280, "y": 658, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "ddb", "type": "aws-dynamo", "label": "DynamoDB — idem.", "x": 80, "y": 862, "width": 130, "height": 110, "fill": "#fff7ed", "stroke": "#f97316" },
{ "id": "cache", "type": "cache", "label": "ElastiCache Redis", "x": 660, "y": 661, "width": 130, "height": 104, "fill": "#ede9fe", "stroke": "#6d28d9" }
],
"edges": [
{ "id": "t1", "source": "users", "target": "dns", "label": "HTTPS", "thickness": 3 },
{ "id": "t2", "source": "dns", "target": "cdn", "label": "alias record", "thickness": 3 },
{ "id": "t3", "source": "cdn", "target": "waf", "thickness": 3 },
{ "id": "t4", "source": "waf", "target": "alb", "label": "clean traffic", "thickness": 3 },
{ "id": "t5", "source": "cdn", "target": "s3", "label": "static assets", "style": "dashed" },
{ "id": "t6", "source": "alb", "target": "ec2a" },
{ "id": "t7", "source": "alb", "target": "ec2b" },
{ "id": "t8", "source": "alb", "target": "ecs", "label": "/checkout" },
{ "id": "t9", "source": "ec2a", "target": "ordr" },
{ "id": "t10", "source": "ec2b", "target": "ordr" },
{ "id": "t11", "source": "ecs", "target": "ordr" },
{ "id": "t12", "source": "ordr", "target": "rdsp", "label": "writes", "thickness": 2 },
{ "id": "t13", "source": "rdsp", "target": "rdss", "label": "sync replica", "style": "dashed" },
{ "id": "t14", "source": "ordr", "target": "cache","label": "cart / session" },
{ "id": "t15", "source": "ordr", "target": "sqs", "label": "order events" },
{ "id": "t16", "source": "sqs", "target": "lam", "label": "trigger" },
{ "id": "t17", "source": "lam", "target": "ddb", "label": "idempotency keys" },
{ "id": "t18", "source": "lam", "target": "s3", "label": "invoice PDFs", "style": "dashed" },
{ "id": "t19", "source": "iam", "target": "lam", "label": "execution role","style": "dashed" },
{ "id": "t20", "source": "ec2a", "target": "nat", "label": "egress" },
{ "id": "t21", "source": "nat", "target": "igw" },
{ "id": "t22", "source": "bastion","target": "ec2a","label": "SSM session", "style": "dashed" }
]
}