AWS Three-Tier Architecture Diagram

This sample draws a classic three-tier web application on AWS: a presentation edge (Route 53 and CloudFront), an application tier (containers on ECS behind an Application Load Balancer), and a data tier (Amazon RDS with Multi-AZ). The diagram shows where each piece runs: which region, which Availability Zone, and which subnet, so that reviewers can check reachability, redundancy and blast radius at a glance.

It is an architecture (topology) diagram, not a UML diagram. UML covers software structure and behaviour; cloud topology diagrams are the companion notation used alongside it, and the closest UML equivalent is the deployment diagram.


1. The diagram

AWS three-tier web application (one region, two AZs) Route 53 Users CloudFront S3 (static) 1 2 /assets/* AWS Region us-east-1 VPC 10.0.0.0/16 Internet GW 3 Availability Zone a Availability Zone b Public subnet Private app subnet Private data subnet Public subnet Private app subnet Private data subnet NAT GW NAT GW Application Load Balancer HTTPS :443, ACM certificate ECS service tasks Fargate, Auto Scaling ECS service tasks Fargate, Auto Scaling 4 RDS primary PostgreSQL writer RDS standby no reads, failover only 5 sync replication ECR Secrets Manager CloudWatch via VPC endpoints: images, secrets, logs and metrics

Follow the numbered badges:

  1. DNS. The browser asks Route 53 for www.example.com; an alias record answers with the CloudFront distribution.
  2. Edge. The user connects to the nearest CloudFront edge over HTTPS. Static files under /assets/* come from a private S3 bucket (origin access control); everything else is forwarded.
  3. Into the VPC. CloudFront calls the internet-facing Application Load Balancer, which lives in the public subnets of both zones.
  4. Application tier. The ALB spreads requests across healthy ECS tasks in the private app subnets. Tasks have no public IPs; outbound calls leave through a NAT gateway, and AWS APIs are reached through VPC endpoints.
  5. Data tier. Tasks read and write the RDS primary in zone a. RDS copies every write synchronously to a standby in zone b, which serves no traffic until a failover.

2. How to read it

Notation used on this page Region / AZ dashed = logical boundary VPC network boundary Subnet solid, coloured by tier green = public blue = private app yellow = private data Service managed AWS box Critical path stateful or entry Standby idle until failover request traffic replication control 1 step no.

Nesting is the main idea: a box inside another box runs inside that boundary. Dashed outlines are logical groupings (region, zone); solid coloured outlines are subnets, coloured by tier. Anything drawn in both zones is redundant; anything drawn once is a single point of failure you should be able to justify.

3. Variant: an Availability Zone fails

Variant: Availability Zone a goes down Application Load Balancer health checks drop AZ a targets Availability Zone a (impaired) Availability Zone b (serving) ECS tasks: unhealthy deregistered after failed checks ECS tasks: scaled out Auto Scaling adds capacity in AZ b Old primary: unreachable replaced later as new standby Standby promoted to primary DNS endpoint flips, about 60-120 s x replication stops

A second view of the same system answers "what happens when zone a disappears?" The ALB health checks mark tasks in zone a unhealthy and stop sending them traffic, Auto Scaling launches replacement tasks in zone b, and RDS promotes the standby, repointing the database DNS name, typically in one to two minutes. Drawing the failure path separately keeps the main diagram clean while proving the design survives the loss of a zone.

4. Pros, cons, and when to use

Pros

Cons

When to use

When not to use

5. Diagrams-as-code

The same topology in D2 (nested containers become boundaries):

direction: down
users: Users
r53: Route 53
cf: CloudFront
s3: S3 static assets
users -> r53: 1 DNS
users -> cf: 2 HTTPS
cf -> s3: /assets/*

region: AWS Region us-east-1 {
  vpc: VPC 10.0.0.0/16 {
    igw: Internet gateway
    alb: Application Load Balancer
    az_a: AZ a {
      nat: NAT gateway
      app: ECS tasks
      db: RDS primary
    }
    az_b: AZ b {
      nat: NAT gateway
      app: ECS tasks
      db: RDS standby {style.stroke-dash: 4}
    }
    igw -> alb
    alb -> az_a.app
    alb -> az_b.app
    az_a.app -> az_a.db
    az_b.app -> az_a.db
    az_a.db -> az_b.db: sync replication {style.stroke-dash: 4}
  }
}
cf -> region.vpc.igw: 3 origin request