Skip to main content

Design a VPC - The Interview Exercise

TL;DR
  • Say requirements first, then the CIDR plan, then subnets per tier per AZ, routing, security, ingress, egress, private service access, hybrid, observability, cost and failure modes, in that order. Interviewers score the order as much as the answer.
  • A strong answer: VPC 10.20.0.0/16, three AZs, a public, app and data subnet in each, one NAT gateway per AZ, security groups chained ALB to app to database, gateway endpoints for S3 and DynamoDB, and a plan for what dies when an AZ dies.
  • Every decision here is owned by another page; this page only strings them into a story. Follow the links when an interviewer digs into one.
  • State assumptions aloud and name the trade-off you took. A design with no stated trade-off reads as memorised.
  • Common weak answers: one NAT gateway "to save money", a database in a public subnet "with a strict security group", a /24 VPC, and no mention of endpoints until the NAT bill arrives.

Mental model​

ANALOGYEveryday

You are drawing the floor plan, fire doors and delivery entrance of a building before anyone moves furniture in. Where the lobby is, which corridors are staff-only, which door the trucks use, and what happens when one wing floods all have to be settled on paper. Moving a wall later is possible but expensive.

Where it breaks: a building has one set of drawings and an architect with final say. An interview design is a conversation: the interviewer changes the requirements halfway through, and your job is to adapt out loud rather than defend the first drawing.

ANALOGYFor engineers

This is a threat model plus a capacity plan, written before the Terraform. The CIDR plan is a schema you cannot migrate cheaply, the route tables are the control flow, and the security groups are the access-control layer. Getting the schema wrong costs a re-IP project, in the same way a bad primary key costs a data migration.

Where it breaks: a schema is only data. A network plan also has a blast radius and a bill: one wrong route or one missing endpoint can take traffic down or run up a per-GB charge, and neither shows in a diagram review.

How it works​

The prompt: design a VPC for a three-tier web application (load balancer, application servers, database) that survives the loss of one availability zone. Draw it and give CIDRs. The walk below is the order to speak in. Each step is two or three lines plus a link to the page that owns the reasoning. AWS names are used for concreteness; the name-mapping table later covers GCP and Azure.

InternetInternet gateway (one per VPC)Availability Zone 1Availability Zone 2Availability Zone 3Gateway endpoints: S3, DynamoDBTransit gateway attachment (own /28 per AZ)VPC 10.20.0.0/16PublicAppDataEndpoints10.20.0.0/2410.20.1.0/2410.20.2.0/2410.20.16.0/2210.20.20.0/2210.20.24.0/2210.20.32.0/2410.20.33.0/2410.20.34.0/2410.20.40.0/2810.20.40.16/2810.20.40.32/28ALB nodeNAT gatewayApp instancesDatabaseInterface endpointsALB nodeNAT gatewayApp instancesDatabaseInterface endpointsALB nodeNAT gatewayApp instancesDatabaseInterface endpoints
One VPC 10.20.0.0/16. Each AZ has a public subnet (ALB node and its own NAT gateway), an app subnet, a data subnet and a small endpoints subnet. Solid, dashed, dotted and dash-dot outlines mark public, app, data and endpoints. Arrows show traffic entering at the internet gateway and moving down the tiers. S3 and DynamoDB are reached through gateway endpoints (route table entries) and on-premises through a transit gateway.

Step 1 - clarify requirements​

Ask before drawing. Each answer changes the design:

  • Load and growth. Requests per second now and in a year, and how many instances or pods that implies. It sets subnet sizes.
  • Data sensitivity and compliance. Regulated data (payment, health) pushes towards no internet gateway on the data and app tiers and endpoints-only access, see the threat model.
  • Availability targets. RTO and RPO, and whether one region is enough. "Survive an AZ" means three AZs and spare capacity; "survive a region" is a different design.
  • Connectivity. Is there an on-premises data centre, another VPC, or a partner? Their CIDRs decide ours.
  • Runtime. VMs or Kubernetes. Pods on the AWS VPC CNI each consume a VPC IP, see Kubernetes networking.

Step 2 - the CIDR plan​

The VPC is 10.20.0.0/16 (65,536 addresses). The plan below is derived with Python's ipaddress module in the worked example; the arithmetic of prefixes is in IPv4 addressing and subnetting, and why the VPC block cannot be resized later is in the cloud network model.

TierAZCIDRUsable hosts (AWS)Route table
Public (ALB, NAT)110.20.0.0/24251public: 0.0.0.0/0 to IGW
Public (ALB, NAT)210.20.1.0/24251public: 0.0.0.0/0 to IGW
Public (ALB, NAT)310.20.2.0/24251public: 0.0.0.0/0 to IGW
App110.20.16.0/221,019app-1: 0.0.0.0/0 to NAT in AZ 1
App210.20.20.0/221,019app-2: 0.0.0.0/0 to NAT in AZ 2
App310.20.24.0/221,019app-3: 0.0.0.0/0 to NAT in AZ 3
Data110.20.32.0/24251data: local only
Data210.20.33.0/24251data: local only
Data310.20.34.0/24251data: local only
Endpoints110.20.40.0/2811local only
Endpoints210.20.40.16/2811local only
Endpoints310.20.40.32/2811local only
TGW attachment110.20.41.0/2811local plus on-prem routes
TGW attachment210.20.41.16/2811local plus on-prem routes
TGW attachment310.20.41.32/2811local plus on-prem routes

Say why: public subnets are small because they hold only load-balancer nodes and NAT gateways. The app tier is the one that grows, so it gets a /22 per AZ. Data is small and stable. Gaps between tiers are deliberate headroom. In the whole plan, 10.20.128.0/17 (half the VPC) is left unallocated. Teams that run many VPCs allocate the VPC block itself from an IP address manager, such as AWS VPC IPAM, so no two VPCs overlap.

Step 3 - routing​

Three route tables, matching the table above. The public table sends 0.0.0.0/0 to the internet gateway. Each app table sends 0.0.0.0/0 to the NAT gateway in the same AZ. The data table has only the implicit local route, so the database has no path to or from the internet at all. "Public subnet" is a routing fact, not a label. Detail in routing in a VPC.

Step 4 - security​

Security groups as a chain: the ALB group allows 443 from the internet, the app group allows the app port from the ALB group (a group reference, not a CIDR), the database group allows 5432 from the app group. Nothing on the data tier allows 0.0.0.0/0. Leave network ACLs at their default of allow-all unless you have a stated reason, such as a subnet-wide explicit deny. Detail in security groups versus NACLs.

Step 5 - ingress​

An Application Load Balancer in the three public subnets terminates TLS (certificate from ACM) and can sit behind AWS WAF. If the requirement is static IPs or raw TCP, use an NLB with one Elastic IP per zone. The choice is the subject of cloud load balancers; where the balancer sits in the whole request is in the request path.

Step 6 - egress​

Private instances need patches, package mirrors and third-party APIs. Give each AZ its own NAT gateway in its public subnet and route that AZ's app subnet to it. Then remove the biggest NAT cost before it exists: gateway endpoints for S3 and DynamoDB (free, a route table entry) and interface endpoints for the AWS APIs the app calls (ECR, CloudWatch Logs, STS). See NAT gateways and egress and private service endpoints.

Step 7 - hybrid and other VPCs​

Attach the VPC to a transit gateway, put a /28 subnet per AZ for the attachment, and connect on-premises with Direct Connect and a VPN as backup. This only works if CIDRs do not overlap, which is why Step 2 matters. Choices between peering, transit gateway and PrivateLink are in private connectivity.

Step 8 - DNS​

A private hosted zone for internal names, and the VPC resolver (the .2 address of the VPC range, as the cloud network model shows) answering for both. Add Route 53 Resolver endpoints only if on-premises needs to resolve cloud names or the reverse (Route 53 Resolver).

Step 9 - observability​

VPC Flow Logs to S3 (or CloudWatch Logs), ALB access logs, and Reachability Analyzer to prove a path exists before and after a change. When something breaks, the order of checks lives in debugging cloud networks (a companion page in this module) and in debugging by layer.

Step 10 - cost​

Three line items, none visible in the diagram: NAT processing per GB, cross-AZ transfer, and interface endpoint hours. Rates are quoted in the cost worked example below, with the date and source.

Step 11 - failure modes​

  • AZ loss. Three AZs and capacity for N+1: the two survivors must carry the full load.
  • NAT AZ loss. Per-AZ NAT and same-AZ routing mean only that AZ's private egress is lost, and that AZ is already down.
  • DNS and limits. Resolver or quota exhaustion looks like an outage with no failed component. Know the quotas.
  • Control plane. Do not rely on launching new capacity during an AZ failure; keep the spare capacity running.

Step 12 - at 10 times the scale​

One VPC per environment per account, a shared networking account, a transit gateway as the hub, centrally managed egress and inspection, and IPAM for CIDRs. On GCP the same pressure leads to Shared VPC. See the multi-VPC whitepaper and the GCP-product view on common network designs.

Worked example: checking the CIDR plan​

Every subnet must sit inside the VPC and none may overlap. Python's ipaddress module checks it, and also shows why 10.20.10.0/22 (a tempting number) is invalid: a /22 block must start on a multiple of 4 in the third octet.

import ipaddress as ip
vpc = ip.ip_network("10.20.0.0/16")
plan = {
"public": ["10.20.0.0/24", "10.20.1.0/24", "10.20.2.0/24"],
"app": ["10.20.16.0/22", "10.20.20.0/22", "10.20.24.0/22"],
"data": ["10.20.32.0/24", "10.20.33.0/24", "10.20.34.0/24"],
"endpoints": ["10.20.40.0/28", "10.20.40.16/28", "10.20.40.32/28"],
"tgw": ["10.20.41.0/28", "10.20.41.16/28", "10.20.41.32/28"],
}
nets = [ip.ip_network(c) for cs in plan.values() for c in cs]
assert all(n.subnet_of(vpc) for n in nets)
assert not any(a.overlaps(b) for i, a in enumerate(nets) for b in nets[i + 1:])
used = sum(n.num_addresses for n in nets)
print(used, round(used / vpc.num_addresses * 100, 2))
print(ip.ip_network("10.20.128.0/17").num_addresses)
ip.ip_network("10.20.10.0/22")
4704 7.18
32768
ValueError: 10.20.10.0/22 has host bits set

The arithmetic, line by line:

  • 15 subnets: 3 x 256 (public) + 3 x 1,024 (app) + 3 x 256 (data) + 6 x 16 (endpoints and TGW) = 768 + 3,072 + 768 + 96 = 4,704 addresses, which is 4,704 / 65,536 = 7.18 percent of the VPC.
  • AWS keeps 5 addresses per subnet (subnet sizing, as of 2026-10), so a /24 has 256 - 5 = 251 usable, a /22 has 1,024 - 5 = 1,019, and a /28 has 16 - 5 = 11.
  • Growth headroom: 10.20.128.0/17 is 32,768 addresses, half the VPC, and untouched. The app tier can grow by 32 more /22 blocks inside that half before anything is renumbered.

Worked example: what one NAT per AZ costs​

Rate assumptions (US East (Ohio), as of 2026-10, from AWS VPC pricing; check the page, rates differ by region): $0.045 per NAT gateway-hour and $0.045 per GB processed. With 730 hours in a month:

  • Three NAT gateways idle: 3 x 730 x $0.045 = $98.55 per month before any traffic.
  • Each GB through NAT adds $0.045, so 10,000 GB adds $450.00. The NAT page works the S3-endpoint saving in full.

That fixed $98.55 is the price of surviving an AZ failure with egress intact, which is the sentence to say when an interviewer asks "why not one NAT?". The scored checklist:

StepWhat to sayRed flag
1 RequirementsAsks load, data sensitivity, RTO and RPO, on-prem link, compliance, Kubernetes or VMsStarts drawing at once
2 CIDR planNon-overlapping 10.x block, /16 VPC, per tier per AZ, headroom, IPAMA /24 for the whole VPC, or 10.0.0.0/16 with no check
3 RoutingPublic to IGW, app to same-AZ NAT, data local onlyAll subnets in one shared route table
4 SecuritySecurity group chain by group reference, default NACL, nothing open on the data tierDatabase in a public subnet with a strict group
5 IngressALB with TLS and WAF, NLB only for static IPs or raw TCPInstances with public IPs behind no balancer
6 EgressNAT per AZ plus gateway and interface endpointsOne NAT for all AZs, no endpoints
7 HybridTransit gateway, Direct Connect with VPN backup, no overlapPeering everything in a mesh
9 ObservabilityFlow logs, ALB logs, Reachability AnalyzerNo way to see traffic
10 CostNames NAT per GB, cross-AZ, endpoint hoursNever mentions the bill
11 Failure modesAZ loss, N+1 capacity, what actually breaksSays multi-AZ is automatic

Deep dive​

Variations the interviewer will throw in​

  • Kubernetes. Pods need their own addresses. On AWS with the VPC CNI they come from the node subnets, so size app subnets for nodes plus pods or add a secondary CIDR for pods; see Kubernetes networking and the EKS IP optimization guide.
  • Multi-region active/active. Two copies of this design with non-overlapping CIDRs, connected by inter-region transit or peering, with traffic steering above it; see global traffic steering.
  • Regulated workload. Remove the internet gateway from the app and data tiers, reach AWS services only through endpoints, and keep NAT out of the picture, as in the private EKS cluster pattern.
  • Overlapping partner CIDR. Do not route to it. Expose the service through PrivateLink, which needs no routing between the two ranges; see private connectivity.

The scoring rubric interviewers use​

Different companies word it differently, but the checklist below is what the scored table above encodes: requirements asked first, no single point of failure, least privilege, cost awareness, observability, and trade-offs named aloud. A design that is correct but silent on trade-offs scores lower than a slightly flawed one that explains its choices.

Cross-cloud name mapping​

ConceptAWSGCPAzureGotcha
Private networkVPC (one region)VPC network (global)Virtual Network (one region)A GCP VPC spans regions, so a 3-region design is one network there
Subnet scopeOne AZOne region, all zonesSpans all AZs of the regionSubnet per AZ is an AWS habit, not a law
Internet entryInternet gateway plus routeDefault route to default-internet-gatewayPublic IPs and default outbound pathGCP has no gateway resource to attach
Instance firewallSecurity group (stateful, on the ENI)VPC firewall rule or policy (stateful)Network security groupOnly AWS has a separate stateless subnet ACL layer by default
Private egressNAT gatewayCloud NAT on a Cloud RouterNAT Gateway on the subnetBilling and port models differ
Private service accessGateway and interface endpointsPrivate Google Access, Private Service ConnectService endpoints, Private EndpointEach needs DNS to resolve privately
Hybrid linkDirect Connect, Site-to-Site VPNCloud Interconnect, Cloud VPNExpressRoute, VPN GatewayDedicated links are slow to provision
Load balancerALB and NLBCloud Load BalancingApplication Gateway, Load BalancerL7 and L4 are split differently per cloud
Many networksTransit gateway, VPC sharingShared VPCHub VNet plus peeringDifferent tools for the same problem

The GCP-product view of these designs lives in the gcp-ace VPC page and common network designs. Sources: AWS VPC, GCP VPC, Azure virtual networks.

What actually breaks when an AZ dies​

  • Compute in that AZ is gone. The auto scaling group launches replacements in the surviving subnets, but only if there is quota and free addresses. This is why survivors need spare capacity already running, and why the per-AZ headroom is a design input: with three AZs, steady-state load per AZ must stay under two thirds of its capacity so two AZs can carry everything.
  • The AZ's NAT gateway goes with it, and so does egress for that AZ's subnets, which is acceptable because those instances are already gone. With a shared NAT in the dead AZ, every other AZ would lose egress too. That is the failure the per-AZ design prevents.
  • Load balancer nodes in the AZ stop serving. Clients keep working because the balancer is a fleet spread across the enabled AZs and its DNS answer drops unhealthy nodes; the behaviour and the cross-zone setting are in cloud load balancers.
  • Stateful systems are the real risk: a database primary in the failed AZ needs a standby elsewhere and a tested failover. A diagram with a database in each AZ but no replication story is incomplete.

Textbook vs real world​

The textbook saysProduction doesWhy
Public subnet and private subnetPublic, app, data, endpoint and transit-attachment subnets, each tier per AZRouting, security groups and blast radius differ per tier, and each attachment wants its own small subnet
One VPCOne VPC per environment per account, plus a shared networking accountAccount boundaries are the strongest blast-radius control; a hub carries what must be shared
Size the subnets for todayReserve unused ranges and plan growth up frontThe VPC primary block cannot be resized and renumbering is a project
Security groups are enoughGroups for access, plus flow logs and an inspection point where policy requiresGroups cannot show what actually happened on the wire

In production​

History and evolution​

HISTORY
  • 2000s The on-premises three-tier design: a DMZ VLAN for web servers, an application VLAN and a database VLAN, separated by firewalls. The tiers in this page are that design, with route tables and security groups in place of physical firewalls.
  • 2009 Amazon launches VPC (announcement), giving customers private address space and a VPN link to their data centre instead of the shared flat network.
  • 2018 AWS Transit Gateway (documentation) replaces meshes of VPC peerings with a regional hub, which is where the 12-step answer ends at scale.
  • 2022 EC2-Classic is retired (AWS notice), leaving the VPC as the only network model.
  • Now Account-per-workload landing zones with a shared networking account, IPAM-managed CIDRs, and endpoints instead of internet egress for AWS services.
  • Next Identity-based access (zero trust) carrying more of the policy that subnets and CIDRs carry today, with the network as a coarse outer layer.

Hands-on​

Carve the plan with Terraform's cidrsubnet(prefix, newbits, netnum); it gives exactly the table above. The skeleton below is a sketch, not a complete module.

locals {
vpc_cidr = "10.20.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
}
 
resource "aws_vpc" "main" {
cidr_block = local.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
}
 
resource "aws_subnet" "public" {
for_each = { for i, az in local.azs : az => i }
vpc_id = aws_vpc.main.id
availability_zone = each.key
cidr_block = cidrsubnet(local.vpc_cidr, 8, each.value) # 10.20.0.0/24 ...
}
 
resource "aws_subnet" "app" {
for_each = { for i, az in local.azs : az => i }
vpc_id = aws_vpc.main.id
availability_zone = each.key
cidr_block = cidrsubnet(local.vpc_cidr, 6, 4 + each.value) # 10.20.16.0/22 ...
}
 
resource "aws_nat_gateway" "per_az" {
for_each = aws_subnet.public
subnet_id = each.value.id
allocation_id = aws_eip.nat[each.key].id
}

Terraform's cidrsubnet(local.vpc_cidr, 6, 4) is 10.20.16.0/22: 6 extra bits make a /22, and block number 4 starts at 4 x 1,024 = 4,096 addresses into the VPC, which is 10.20.16.0. Verify what you built against the plan:

aws ec2 describe-subnets --filters Name=vpc-id,Values=vpc-0abc123 \
--query 'Subnets[].[CidrBlock,AvailabilityZone,AvailableIpAddressCount]' --output table

Look at AvailableIpAddressCount per subnet: it should be the usable count from the table minus anything already running (251 for a fresh /24). Then run the plan check from the worked example before applying, so an overlapping CIDR fails in review and not in terraform apply. Reachability Analyzer then confirms a path from the ALB to an app instance and proves that none exists from the internet to the database. These commands assume the AWS CLI v2; the Python check runs the same on macOS and Linux.

Gotchas​

GOTCHAS4
One NAT gateway is fine
A database in a public subnet is fine with a strict security group
A /24 is enough for the VPC
Endpoints can wait until later

Interview questions​

INTERVIEWDesign a VPC for a 3-tier web app in 3 AZs. Draw it and give CIDRs.mid
Show answer

Clarify load, sensitivity, availability and connectivity first. Then: VPC 10.20.0.0/16, per AZ a public /24 (ALB, NAT), an app /22 and a data /24, with headroom left. Public routes to the IGW, app routes to a same-AZ NAT, data is local only. Security groups chain ALB to app to database. ALB with TLS in front, gateway endpoints for S3 and DynamoDB, flow logs on. Close with what happens when an AZ dies.

Follow-ups:

  • Why a /22 for app? It is the tier that grows, and pods or autoscaling consume addresses; 1,019 usable per AZ beats 251.
  • What would you change for Kubernetes? Size for pods or add a secondary CIDR, see Kubernetes networking.
INTERVIEWA private instance needs the internet. How, and what about HA and cost?mid
Show answer

Route its subnet's 0.0.0.0/0 to a NAT gateway in a public subnet, which has a route to the internet gateway. NAT lets it start connections out and blocks unsolicited ones in. For HA, one NAT per AZ with same-AZ routing. For cost, NAT bills per hour and per GB, so move S3 and DynamoDB to gateway endpoints.

Follow-ups:

  • What does three NATs cost idle? 3 x 730 x $0.045 = $98.55 per month at the US East (Ohio) rate, as of 2026-10 (pricing).
  • Is there an alternative to the zonal gateway? AWS offers a regional NAT gateway mode; see NAT gateways and egress.
INTERVIEWWhy can't I reach my EC2 instance even though it has a public IP?mid
Show answer

A public IP is necessary, not sufficient. Check in order: the subnet's route table has 0.0.0.0/0 to an internet gateway, the security group allows the port from your source, the network ACL allows the port both ways (it is stateless, so the return ephemeral ports too), the instance's own firewall and service are listening, and the OS has a default route. Reachability Analyzer tests the first three without sending packets.

Follow-ups:

  • Which check fails most? Security group source or a missing route, in that order for new instances; see security groups versus NACLs.
  • Where is the structured version? In debugging cloud networks, the companion page in this module.
INTERVIEWYour company and a partner both use 10.0.0.0/16. How do you connect?senior
Show answer

Overlapping ranges cannot be peered or routed. The fast fix is PrivateLink: the partner exposes a service, you consume it through an interface endpoint with an IP from your own range, and no routes are exchanged. A NAT translating one side is a brittle workaround. The long-term fix is to renumber one side, and to allocate future ranges from IPAM.

Follow-ups:

  • What does PrivateLink not give you? General any-to-any connectivity; it exposes one service, in one direction.
  • How do you stop it recurring? A central IPAM and a rule that no VPC is created with a hand-picked block; see the cloud network model.
INTERVIEWHow does traffic reach S3 without crossing the internet? What controls access?senior
Show answer

A gateway endpoint adds a route to the S3 prefix list pointing at the endpoint, so S3 traffic leaves the subnet over the AWS network without NAT or an internet gateway, and it is free. Access control is a pair: an endpoint policy on the VPC side and a bucket policy that can require the request to come from that endpoint (S3 bucket policy for VPC endpoints).

Follow-ups:

  • Does it work from on-premises? Not through a gateway endpoint; on-premises needs an interface endpoint, see private service endpoints.
  • Why does it not use DNS? A gateway endpoint works through routing; interface endpoints work through DNS.
INTERVIEWWhat happens when an AZ dies, and what actually breaks?senior
Show answer

Compute, NAT gateway and load balancer nodes in that AZ stop. Because every AZ has its own NAT and routes to it, the other AZs keep egress. The load balancer keeps serving from the surviving AZs, and the autoscaling group needs spare capacity there: with three AZs, steady load must stay under two thirds of per-AZ capacity. The hard part is state: the database needs a standby in another AZ and a tested failover.

Follow-ups:

  • Why not rely on launching new instances? The failure may exhaust capacity or hit quotas exactly when everyone else is also launching, so keep spare capacity running.
  • What is the cheapest improvement? Test it: drain one AZ in a game day and watch what breaks.
INTERVIEWScale this to 40 accounts and an on-prem data centre.senior
Show answer

Move to account-per-workload with a shared networking account holding a transit gateway. Each VPC attaches (a /28 subnet per AZ), Direct Connect with a VPN backup lands on the transit gateway through a gateway, and CIDRs come from IPAM so nothing overlaps. Egress and inspection are centralised in a dedicated VPC.

Follow-ups:

  • How do you design the transit gateway route tables? Separate tables per trust zone, for example production, non-production and shared services, so propagation controls who can reach whom; see private connectivity.
  • What changes on GCP? Shared VPC and VPC peering carry much of this; see common network designs.
INTERVIEWCut this design's network bill by 30 percent. Where would you look?senior
Show answer

Measure first: flow logs and the billing breakdown by usage type, not guesses. Usual wins, in order: send S3 and DynamoDB through gateway endpoints, avoid cross-AZ NAT and cross-AZ chatter (same-AZ routing, zone-aware calls), cache or mirror big downloads, and drop idle NAT gateways in non-production. Weigh each: an interface endpoint costs an hourly fee per AZ.

Follow-ups:

  • Where is it measured? Flow logs plus the cost and usage report, filtered by data transfer and NAT usage types.
  • Which saving is a trap? Dropping to one NAT gateway: it saves $65.70 per month of fixed charge (2 x 730 x $0.045, as of 2026-10) and creates a single point of failure.

Fun facts​

FACTSTrivia worth knowing
  • A /22 is not valid at 10.20.10.0: its start must be a multiple of 4 in the third octet, and Python rejects it with "host bits set", as the worked example shows.
  • Terraform's cidrsubnet(prefix, newbits, netnum) carves exactly this plan, so the whole table can be generated from three integers per tier.
  • In this plan 92.8 percent of the VPC is unallocated, and an interviewer still may ask where you would put the next tier.

Cheat sheet​

NUMBERSNumbers to remember
  • /16 - the VPC block, 65,536 addresses
  • 5 - addresses AWS reserves per subnet, so a /24 has 251 usable
  • 1,019 - usable addresses in a /22
  • 3 NATs idle - 3 x 730 x $0.045 = $98.55 per month (US East Ohio, as of 2026-10)
  • 2/3 - maximum steady load per AZ if two of three AZs must carry everything