AWS VPC Design — Learning Roadmap

Abhishek Bahukhandi
AWS VPC Design — Learning Roadmap
Most people learn AWS networking backwards. They open the console, click "Create VPC", pick a CIDR block because a tutorial said so, and then spend the next two years confused about why one subnet reaches the internet and another doesn't. VPC isn't hard — it's just layered, and if you skip a layer the ones above it stop making sense.
This roadmap is the order I'd actually learn it in: 22 topics, each one building on the last. Nothing here assumes you already know networking. By the end you should be able to sketch a production VPC on a whiteboard and defend every line you drew.
How to use this roadmap
Don't read all 22 topics in one sitting. Take one stage at a time, build the thing in a real (free-tier) AWS account, break it, fix it, then move on. Networking is muscle memory — reading about route tables teaches you far less than staring at a broken one for twenty minutes.
Stage 1 — Foundations (before you touch AWS)
1. Networking Fundamentals
Start below AWS entirely. You need a working mental model of what a packet is, what an IP address and a port do, the difference between TCP and UDP, and what a router versus a switch actually does. Every AWS networking feature is a managed version of something that already existed — a route table is a route table, a security group is a stateful firewall. Learn the generic concept first and the AWS name becomes a label, not a new idea.
You're ready to move on when: you can explain, out loud, what happens between typing a URL and the page loading — DNS lookup, TCP handshake, request, response.
2. IPv4 + CIDR
An IPv4 address is 32 bits, usually written as four numbers. CIDR notation like 10.0.0.0/16 just says "the first 16 bits are fixed — the network — and the rest are mine to hand out."
The single most useful thing to memorise is how the prefix length maps to address count:
| CIDR | Total addresses | Usable in AWS |
|---|---|---|
| /16 | 65,536 | 65,531 |
| /20 | 4,096 | 4,091 |
| /24 | 256 | 251 |
| /28 | 16 | 11 |
Also learn the RFC 1918 private ranges — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 — because your VPC CIDR should come from one of them.
3. Subnetting
Subnetting is splitting one CIDR block into smaller, non-overlapping blocks. If your VPC is 10.0.0.0/16, you might carve it into 10.0.0.0/20, 10.0.16.0/20, 10.0.32.0/20 and so on — one per subnet, per availability zone.
The rule that bites everyone later: overlapping CIDRs can never be peered or connected. If your dev VPC and prod VPC are both 10.0.0.0/16, they can never talk to each other without NAT gymnastics. Plan your address space across the whole organisation before you create the first VPC.
4. AWS Regions + Availability Zones
A Region is a geographic area (say ap-south-1, Mumbai). An Availability Zone is one or more physically separate data centres inside that region, with independent power and cooling, connected by low-latency links.
This matters for design because a VPC spans all AZs in a region, but a subnet lives in exactly one AZ. That one sentence is the reason every production diagram you'll ever see has subnets duplicated across two or three AZs.
Stage 2 — The core building blocks
5. VPC
A Virtual Private Cloud is your own isolated slice of the AWS network. You give it a CIDR block, and everything you launch inside it gets a private IP from that range. By default nothing inside a VPC can reach the internet and nothing on the internet can reach in — every bit of connectivity after this is something you deliberately add.
Pick your CIDR generously but not carelessly. A /16 is the common default; going smaller than /20 for a real workload will hurt you when you add subnets, AZs, and EKS pods later.
6. Subnets
Subnets divide your VPC into AZ-scoped segments. AWS reserves five addresses in every subnet — the first four and the last — so a /24 gives you 251 usable IPs, not 256.
A practical layout for a 10.0.0.0/16 VPC across two AZs:
AZ-a public 10.0.0.0/20
AZ-a private 10.0.16.0/20
AZ-a data 10.0.32.0/20
AZ-b public 10.0.64.0/20
AZ-b private 10.0.80.0/20
AZ-b data 10.0.96.0/20
Leaving gaps between blocks is intentional — you will want room to grow.
7. Route Tables
A route table is a list of "traffic for this destination goes to that target". Every subnet is associated with exactly one route table, and every route table starts with a local route covering the VPC CIDR — that's why all subnets in a VPC can reach each other out of the box.
Destination Target
10.0.0.0/16 local <- always present
0.0.0.0/0 igw-0abc123 <- makes the subnet public
Most connectivity problems in AWS come down to a missing or wrong route. When something can't reach something else, check the route table before you touch anything else.
8. Internet Gateway
An Internet Gateway (IGW) is a horizontally-scaled, highly available component you attach to a VPC to allow traffic to and from the public internet. Attaching it does nothing on its own — it only takes effect when a route table points 0.0.0.0/0 at it and the instance has a public IP.
9. Public vs Private Subnets
There is no checkbox called "public". A subnet is public purely because its route table has a default route to an Internet Gateway. That's the entire definition.
- Public subnet — route to IGW. Load balancers, bastion hosts, NAT gateways live here.
- Private subnet — no route to IGW. Application servers live here.
- Isolated / data subnet — no route out at all. Databases live here.
The design instinct to build: put as little as possible in public subnets.
10. NAT Gateway
Private instances still need outbound internet for package updates, API calls, and pulling container images — but you don't want inbound connections reaching them. A NAT Gateway, placed in a public subnet, does exactly that: it translates outbound traffic from private instances to its own Elastic IP, and drops anything unsolicited coming the other way.
The classic beginner mistake
Putting the NAT Gateway in a private subnet. It needs a route to the Internet Gateway itself, so it must sit in a public subnet — and the private subnets' route tables then point 0.0.0.0/0 at the NAT, not at the IGW.
The second classic mistake is cost: NAT Gateways bill hourly and per GB processed. One per AZ is the highly-available pattern, but it's also one of the most common surprise line items on an AWS bill.
Stage 3 — Securing the network
11. Security Groups
Security groups are stateful firewalls attached to an elastic network interface — effectively, to an instance. If you allow an inbound request, the response is automatically allowed back out; you don't write a return rule.
They're allow-only: there is no deny rule. The most important trick is that a security group can reference another security group as its source. Instead of writing CIDR ranges, you say "the database SG accepts port 5432 from the app SG" — and it keeps working no matter how many app servers come and go.
12. Network ACLs
NACLs are stateless firewalls attached to a subnet. Stateless means you must explicitly allow return traffic — which is why NACL rules almost always include the ephemeral port range 1024-65535 outbound.
They're evaluated in rule-number order, support explicit deny, and apply to every resource in the subnet. In practice: use security groups for day-to-day access control, and reach for NACLs only when you need a blunt subnet-wide block (for example, blackholing a malicious IP range).
13. VPC Endpoints
By default, an instance in a private subnet talking to S3 or DynamoDB routes out through the NAT Gateway and across the public internet. VPC Endpoints keep that traffic on the AWS private network instead.
- Gateway endpoints — S3 and DynamoDB only. Free. They add a route to your route table.
- Interface endpoints (PrivateLink) — most other AWS services. They create an ENI with a private IP in your subnet, and they're billed per hour and per GB.
Gateway endpoints for S3 are close to free money: less NAT data-processing cost, and traffic that never leaves the AWS backbone.
Stage 4 — Addressing, names, and getting traffic in
14. DNS / DHCP
Every VPC gets AWS's DNS resolver at the VPC CIDR base plus two (for 10.0.0.0/16, that's 10.0.0.2). Two VPC attributes control behaviour: enableDnsSupport turns the resolver on, and enableDnsHostnames decides whether instances get public DNS names. Private Hosted Zones in Route 53 let you run internal names like db.internal.example.com that only resolve inside your VPC.
If you enable a VPC endpoint or a peering connection and names mysteriously fail to resolve, these two flags are the first place to look.
15. Elastic IP / Public IP / Private IP
- Private IP — from your subnet's CIDR, stays with the instance for its lifetime.
- Public IP — auto-assigned, and lost the moment you stop the instance.
- Elastic IP — a static public IPv4 you own and can remap between instances.
Worth knowing: since 2024 AWS charges for all public IPv4 addresses, attached or not. Don't hoard Elastic IPs, and prefer a load balancer over per-instance public IPs.
16. Load Balancers
Elastic Load Balancing is how real traffic gets into your VPC. An internet-facing ALB sits in your public subnets across at least two AZs and forwards to targets in the private subnets — which is what lets your application servers have no public IP at all.
- ALB — Layer 7, HTTP/HTTPS, path and host routing. The default for web apps.
- NLB — Layer 4, TCP/UDP, extreme throughput, static IPs per AZ.
- GWLB — for inserting third-party network appliances into the traffic path.
Stage 5 — Connecting VPCs and the outside world
17. VPC Peering
Peering connects two VPCs so they can route to each other with private IPs. It's simple and cheap, but it has two hard limits worth internalising early: CIDRs must not overlap, and peering is not transitive — if A peers with B and B peers with C, A still cannot reach C.
Peering is great for two or three VPCs. At ten VPCs you'd need 45 connections, which is exactly the problem the next topic solves.
18. Transit Gateway
A Transit Gateway is a regional hub that every VPC, VPN, and Direct Connect attaches to once — turning a tangled mesh into a hub-and-spoke. It supports transitive routing, and its route tables let you control which spokes can reach which (for example, letting every VPC reach a shared-services VPC while keeping dev and prod completely isolated).
This is the backbone of essentially every multi-account AWS network design.
19. VPN / Direct Connect
- Site-to-Site VPN — IPsec tunnels over the public internet. Fast to set up, cheap, but bandwidth and latency depend on the internet.
- Direct Connect — a dedicated private circuit from your data centre into AWS. Consistent latency and higher throughput, but it takes weeks to provision and costs considerably more.
The common production pattern is Direct Connect as primary with a VPN as automatic backup.
20. VPC Flow Logs
Flow Logs capture metadata about IP traffic going to and from network interfaces — source, destination, ports, bytes, and crucially ACCEPT or REJECT. They can be published to CloudWatch Logs or S3.
This is your debugging tool of last resort and your security audit trail at the same time. When connectivity fails and every rule "looks right", a stream of REJECT entries tells you instantly whether traffic is even arriving, and which layer dropped it.
Stage 6 — Putting it together
21. Multi-AZ VPC Architecture
Now combine everything. The canonical resilient layout:
- One VPC with a
/16CIDR, spanning two or three AZs. - A public, a private, and a data subnet in each AZ.
- An Internet Gateway attached to the VPC, with the public subnets routing
0.0.0.0/0to it. - A NAT Gateway in each AZ's public subnet, with each AZ's private subnet routing to its own NAT — so losing one AZ doesn't take out the others.
- An ALB across the public subnets, forwarding to application instances in the private subnets.
- An RDS Multi-AZ deployment in the data subnets, reachable only from the application security group.
The test of the design is simple: mentally delete an entire AZ. If anything stops working, it wasn't multi-AZ.
22. Production VPC Design
Production adds the concerns that tutorials skip:
- Address planning — allocate non-overlapping CIDRs across every account and environment before anyone builds anything.
- Multi-account topology — separate accounts for dev, staging, and prod, joined through a Transit Gateway with a shared-services VPC.
- Least-privilege security groups — reference security groups, not CIDRs, and never leave
0.0.0.0/0on port 22. - Endpoints over NAT — gateway endpoints for S3 and DynamoDB, interface endpoints for the AWS APIs you call constantly.
- Observability — Flow Logs enabled everywhere, shipped to S3, with alarms on anomalous REJECT volume.
- Infrastructure as code — the whole VPC in Terraform or CDK. A VPC assembled by hand in the console is a VPC nobody can rebuild.
- Cost awareness — NAT data processing, interface endpoints, and cross-AZ traffic are the three line items that quietly grow.
The one-line summary
A VPC is a CIDR block. Subnets slice it per AZ. Route tables decide where traffic goes. Gateways connect it outward. Security groups and NACLs decide who's allowed. Everything else — peering, Transit Gateway, endpoints, flow logs — is a variation on those five ideas.
What to build as you go
Reading this roadmap takes an hour. Actually learning it takes a few weekends of building. A good progression:
- Create a VPC with one public subnet, launch an EC2 instance, SSH into it.
- Add a private subnet and a NAT Gateway; prove the private instance can run a package update but can't be reached from outside.
- Add a second AZ and an ALB in front of two instances; terminate one and watch traffic shift.
- Move the database into an isolated subnet and lock it to the app's security group only.
- Add an S3 gateway endpoint and confirm in Flow Logs that the traffic no longer goes through the NAT.
- Delete it all and rebuild it from Terraform in one command.
Step six is the one that turns knowledge into a skill. Until you can recreate the whole network from code, you don't really own the design yet.