Skip to content
Cloud architecture templates

AWS — Three-Tier Web Application, Multi-AZ

The reference architecture, drawn correctly and reported clean: a public load balancer, application servers in private subnets across two availability zones, and the database isolated with a standby in the other zone. Copy this one. Every check runs and finds nothing, which the engine states rather than implies.

Template previewCloud architecture
Three-tier web applicationAn AWS architecture diagram: 10 resources in 12 scopes (1 network, 2 availability zones), joined by 11 connections. Categories drawn: Compute, Storage, Databases, Networking, Clients. No error or warning across 10 resources and 11 edges, every line read; 1 ran only in part — so this is a clean result on the part that could be checked, not a clean bill of health.Three-tier web applicationAWS · 10 resources · 12 scopes · 1 network · 2 zones · 11 connectionsNo error or warning across 10 resources and 11 edges, every line read; 1 ran only in part — so this is a clean result on the part that could be checked,not a clean bill of health.Internetintern…8AccountAcme Production8Regionus-east-18NetworkMain VPC10.0.0.0/168+Availability zoneus-east-…8Availability zoneus-east-…8SubnetPubl…10.0.1.0…public8+SubnetApp tie…10.0.11.…private8+SubnetData…10.0.21.…isolated8+SubnetPubl…10.0.2.0…public8+SubnetApp tie…10.0.12.…private8+SubnetData…10.0.22.…isolated8+Customers—2+Public loadbalanceraws2+Internetgatewayaws5+Static assetsaws1+NAT gateway Aaws5+Web server Aaws×22+Orders(primary)awsHA2+NAT gateway Baws5+Web server Baws×22+Orders(standby)awsHA3+https 443http 8080http 8080postgres 5432postgres 5432replications3 apis3 apiLegendComputeStorageDatabasesNetworkingClientsRequest trafficData movementReplicationDepends onChecks — what ran, and what could notWhether the internet reaches something that ho…ran over 6 subjects, found nothingWhether anything holding data at rest sits in …ran over 2 subjects, 1 gap — a partial passWhether anything claiming redundancy is spread…ran over 4 subjects, found nothingEdges that leave one network for another, or c…ran over 10 subjects, found nothingResources that appear in no edge at all. A leg…ran over 10 subjects, found nothingEvery id an edge or a scope names is one that …ran over 10 subjects, found nothingEach id is declared once. Two declarations mak…ran over 22 subjects, found nothingType words that did not resolve. A hole in thi…ran over 10 subjects, found nothingDeclared ranges: that each parses, sits inside…ran over 7 subjects, found nothingWhether every line was read and no shape cap b…ran over 22 subjects, found nothingFindings1`assets` holds data at rest and sits inside no subnet at all, so nothing in this document says whether it is publicly routable and this check had nothing to read.in the figure: assets2The walk reached 6 resources from the internet; every one of the 2 that hold data at rest — `db-a` and `assets` — sits behind an ingress.in the figure: customers, lb, web-a, web-b, db-a +1 more3Every one of the 2 datastores this check could read — `db-a` and `db-b` — sits in a subnet declared private or isolated.in the figure: db-a (badge 2), db-b42 resources claim redundancy from inside one zone and are drawn with a replicated peer in another — `db-a` and `db-b` — so the picture supports the claim.in the figure: db-a (badge 2), db-b (badge 3)5Every edge this check could read stays inside one network, stays outside all of them, or names a gateway to cross at; 10 endpoints were read across 1 declared network.in the figure: customers (badge 2), lb (badge 2), web-a (badge 2), web-b (badge 2), db-a (badge 2) +5 more6All 10 declared resources appear in at least one edge.in the figure: customers (badge 2), lb (badge 2), gw (badge 5), assets (badge 1), nat-a (badge 5) +5 more7All 10 ids named by edges and scopes were declared somewhere in this document.in the figure: customers (badge 2), lb (badge 2), web-a (badge 2), web-b (badge 2), db-a (badge 2) +5 more8All 22 declared ids are distinct.in the figure: internet, prod, us-east-1, vpc-main, us-east-1a +17 more9All 10 resources resolved to a type this engine knows, so every check above had the full vocabulary to read.in the figure: customers (badge 2), lb (badge 2), gw (badge 5), assets (badge 1), nat-a (badge 5) +5 more10All 7 declared ranges parse, each of the 6 drawn inside an addressed network sits inside it, and no two ranges under one parent share an address. The 6 subnets thathave instances drawn in them hold them. Ranges under different parents were not compared — two networks numbered alike is ordinary and correct.in the figure: vpc-main (badge 8), pub-a (badge 8), app-a (badge 8), data-a (badge 8), pub-b (badge 8) +2 more11Every line was read and no shape cap bit: the 22 declarations above are the whole document, so the counts are totals rather than floors.

Make it your own.

title "Three-tier web application"
provider aws

internet {
  user customers "Customers"
}

cloud prod "Acme Production" {
  region us-east-1 {
    network vpc-main "Main VPC" cidr 10.0.0.0/16 {
      alb lb "Public load balancer"
      igw gw "Internet gateway"
      s3 assets "Static assets"

      zone us-east-1a {
        subnet pub-a "Public A" public cidr 10.0.1.0/24 {
          nat nat-a "NAT gateway A"
        }
        subnet app-a "App tier A" private cidr 10.0.11.0/24 {
          ec2 web-a "Web server A" count 2 tier web
        }
        subnet data-a "Data A" isolated cidr 10.0.21.0/24 {
          rds db-a "Orders (primary)" multi-az
        }
      }

      zone us-east-1b {
        subnet pub-b "Public B" public cidr 10.0.2.0/24 {
          nat nat-b "NAT gateway B"
        }
        subnet app-b "App tier B" private cidr 10.0.12.0/24 {
          ec2 web-b "Web server B" count 2 tier web
        }
        subnet data-b "Data B" isolated cidr 10.0.22.0/24 {
          rds db-b "Orders (standby)" multi-az
        }
      }
    }
  }
}

customers -> lb : https 443
lb -> web-a : http 8080
lb -> web-b : http 8080
web-a -> db-a : postgres 5432
web-b -> db-a : postgres 5432
db-a <=> db-b : replication
web-a => assets : s3 api
web-b => assets : s3 api
lb ..> gw
web-a ..> nat-a
web-b ..> nat-b