Networking Foundations: CIDR, Subnets & VPC
Networking only feels hard because it's taught as text. Underneath it's just address ranges and road signs, so we'll make it visual and let you poke at it.
From your mentor
Don't memorise CIDR, feel it. Drag the slider in the next section until /24 = 256 and /16 = 65,536 are obvious. Once ranges click, subnets, routes, and firewalls are easy.
A VPC is just a fenced yard for your servers, you already understand this.
In 10 minutes you’ll draw one from memory. You do NOT need NAT, peering, or CIDR math yet, ignore them for now.
Pick your way in, same idea, 5 doors
A VPC is a fenced yard you rent in the cloud. You put your computers inside the fence, and you decide who’s allowed in and who’s allowed out. Nothing else can wander in. That’s the whole idea, every term below just names the fence, the gates, and the guards.
It’s just ranges and routes
A VPC is your own private slice of the AWS network. Everything in this lesson is one of two ideas: which addresses exist, and where traffic is allowed to go.
In plain English
CIDR, finally made interactive
A CIDR block is an IP plus a /prefix. The prefix says how many bits are fixed, the rest are free addresses. Stop reading and drag it:
Total addresses
256
= 2(32−24)
Usable in AWS
251
total − 5 reserved
The 5 IPs AWS reserves in every subnet
The pattern: the smaller the prefix number, the bigger the block. Each step down doubles the addresses, /25 is 128, /24 is 256, /23 is 512. AWS allows VPC and subnet blocks from /16 (65,536) down to /28 (16).
AWS always takes 5 addresses per subnet
In every subnet, the first four IPs (network, VPC router, DNS, future) and the last (broadcast) are reserved. So a/24 gives you 251 usable, not 256, and a tiny /28 leaves just 11. Plan small subnets with that −5 in mind.Where subnets actually come from
A subnet isn't a separate thing you invent, it's a slice you carve out of the VPC's range, pinned to one Availability Zone.
10.0.0.0/24
AZ-a · 256 IPs (251 usable)
10.0.1.0/24
AZ-a · 256 IPs (251 usable)
10.0.2.0/24
AZ-b · 256 IPs (251 usable)
10.0.3.0/24
AZ-b · 256 IPs (251 usable)
Each subnet is just a slice of the VPC’s range, pinned to one Availability Zone. “Public” vs “private” isn’t a setting on the subnet, it’s decided by its route table (next).
Always span at least two AZs
A subnet lives in exactly one AZ. For anything resilient, create a matching subnet in a second AZ (e.g. public + private in AZ-a and AZ-b) so one data-centre failure can’t take you down.Route tables & the internet gateway
A route table is the list of road signs for a subnet: 'traffic for this range goes that way.' It's what makes a subnet public or private.
Every subnet has a route table. It always has a local route (traffic inside the VPC stays in the VPC). What you add decides everything else:
Nice, that’s the win
0.0.0.0/0 → IGW to a subnet’s route table and it’s public. Leave that line out and the same subnet is private. One road sign is the whole difference.Private subnets reach out via NAT
A private subnet often still needs outbound internet (to pull updates) without being reachable from it. That’s a NAT gateway: it lives in a public subnet, and the private subnet routes0.0.0.0/0 → NAT. (NAT has a real cost, more in the next lesson.)Security Groups vs NACLs
Two firewalls, two layers. The difference, where they sit and whether they remember traffic, is a guaranteed interview question.
Security Group
stateful- • Wraps the instance (its network interface), the door on each room.
- • Allow rules only, there’s no deny.
- • Stateful: allow a request out and the reply is auto-allowed back.
- • Your primary tool, start here.
Network ACL
stateless- • Guards the whole subnet, the gate to the block.
- • Allow and deny rules, evaluated in number order.
- • Stateless: you must allow return traffic (ephemeral ports) explicitly.
- • A backup layer for subnet-wide deny rules.
Worth pondering
Putting it together: a real VPC
Here's the layout you'll build for almost every app, public subnets for the front door, private subnets for the valuables.
VPC · 10.0.0.0/16
Public subnet · 10.0.0.0/24
Route table: 0.0.0.0/0 → IGW
Private subnet · 10.0.1.0/24
Route table: 0.0.0.0/0 → NAT
The only difference between public and private here is one route-table line: a public subnet has a route to the IGW; a private one routes out via NAT (or not at all).
The golden pattern
Public subnets hold only what must face the internet (load balancer, NAT). Everything valuable, app servers, databases, goes in private subnets with no inbound route from the internet. This single habit prevents most network breaches.DNS inside your VPC
Every VPC runs a hidden DNS resolver so your instances can resolve names. Two toggles control it, and they cause more head-scratching than almost anything else.
| Attribute | Default | What it does |
|---|---|---|
| enableDnsSupport | On | Turns on the built-in resolver at the VPC base +2 (and 169.254.169.253) |
| enableDnsHostnames | Off (custom VPC) | Gives instances public DNS names, needed by many features and endpoints |
In plain English
10.0.0.2, which is exactly why “.2” was one of the five reserved IPs back in Section 2. For hybrid setups (resolve on-prem names from AWS, or vice-versa) you add Route 53 Resolver inbound/outbound endpoints.Private, public & Elastic IPs, and the ENI
Three kinds of IP address, and the one virtual device they all hang off. Get these straight and a lot of 'why can't it connect' questions answer themselves.
| IP type | Lifetime | Notes |
|---|---|---|
| Private IP | For the instance’s whole life | From the subnet range; always present; free |
| Public IP | Released on stop/terminate | Auto-assigned, changes every restart; now billed |
| Elastic IP (EIP) | Static, you own it | Survives restarts; billed whenever allocated |
All of them live on an ENI (Elastic Network Interface), a virtual network card that carries the IPs, MAC address, and security groups. You can detach an ENI from one instance and attach it to another, which is how some failover patterns move an identity between machines.
Public IPv4 now costs money
Since 1 Feb 2024, every public IPv4 address is $0.005/hour (~$3.60/month, ~$43/year), whether attached or sitting idle, including unused Elastic IPs. (The free tier covers 750 hours/ month for the first 12 months.) Don’t hoard EIPs, release ones you’re not using, and prefer private subnets or IPv6 where you can.Getting out: NAT, egress-only & VPC endpoints
Private subnets often still need to reach out, for updates, APIs, or AWS services. How they egress is its own topic, and the wrong choice is a classic surprise bill.
| Path out | What it’s for | Cost |
|---|---|---|
| NAT gateway | IPv4 outbound from private subnets | $0.045/hr per AZ + $0.045/GB, pricey |
| Egress-only IGW | IPv6 outbound-only (no inbound) | Free (data transfer still applies) |
| Gateway VPC endpoint | Private path to S3 & DynamoDB only | Free |
| Interface VPC endpoint | Private path to most AWS services (PrivateLink) | $0.01/hr per AZ + $0.01/GB |
Nice, that’s the win
Security Groups & NACLs: the deep mechanics
You met stateful vs stateless earlier. Here's what actually bites in production, the details interviewers and outages both probe.
| Detail | Security Group | Network ACL |
|---|---|---|
| Operates at | The instance (its ENI) | The whole subnet |
| Rules | Allow only | Allow + deny, evaluated low → high number |
| State | Stateful, return traffic auto-allowed | Stateless, must allow return on ephemeral ports 1024–65535 |
| Defaults | Default SG allows all intra-group; a new SG denies inbound | Default NACL allows all; a custom NACL denies all until you add rules |
| References | Can allow another SG as the source | CIDR ranges only |
| Limits (default) | 60 inbound / 60 outbound rules; 5 SGs per ENI | 20 rules (adjustable) |
Reference SGs, don’t hardcode CIDRs
The pro move: let the database’s SG allow the app tier’s SG as its source, not an IP range. It keeps working as instances scale and IPs churn, and reads like intent (“the app may reach the DB”).Routing detail: longest prefix wins
When several routes match a destination, the most specific (longest prefix) route wins, a/32 beats a /24 beats 0.0.0.0/0. The VPC’s local route always wins inside the VPC and can’t be removed.Seeing your traffic: Flow Logs & Reachability Analyzer
When something can't connect, you don't guess which layer blocked it, you look. AWS gives you two tools for exactly that.
| Tool | What it tells you |
|---|---|
| VPC Flow Logs | ACCEPT/REJECT records for every network interface → CloudWatch Logs or S3. A REJECT shows you exactly what was blocked. |
| Reachability Analyzer | Computes whether a path exists between two resources and names the hop (SG, NACL, route) that blocks it. |
The debugging order for “can’t connect” is always the same: check the security group, then the NACL, then the route table. Flow Logs’ REJECT lines point you straight at the guilty layer instead of guessing.
AWS docs: ec2 create-flow-logs# capture only blocked traffic, the fastest way to find a misconfigured SG or NACL$ aws ec2 create-flow-logs --resource-type VPC --resource-ids <vpc-id> --traffic-type REJECT --log-group-name vpc-rejects --deliver-logs-permission-arn <role-arn>
How this shows up in interviews
“Design the network for a simple web app with a database. What goes where?”
How to answer it
Draw the VPC out loud: CIDR, subnets across AZs, public vs private by route, and the firewalls. Naming the IGW/NAT split and SG-vs-NACL shows you’ve actually built one.
- 1A VPC with, say, a 10.0.0.0/16 CIDR, room for many subnets.
- 2Public + private subnets in at least two AZs for resilience.
- 3Load balancer (and NAT gateway) in the public subnets; app servers and the database in private subnets.
- 4Public subnets route 0.0.0.0/0 → Internet Gateway; private subnets route outbound via NAT, with no inbound internet route.
- 5Security Groups (stateful) per tier as the primary control; NACLs only for coarse subnet-wide deny rules.
Green flags
- Puts the database in a private subnet by default
- Knows public vs private is a route, not a flag
- Spans multiple AZs without being asked
Red flags
- Puts everything in one public subnet
- Thinks a Security Group can have deny rules
- Can’t explain why a /24 has 251 usable IPs
Q.How many usable IPs in a /24, and why?
A.251. A /24 is 256 addresses and AWS reserves 5 in every subnet.
- 256 = 2^(32−24).
- Reserved 5: network address, VPC router, AWS DNS, one for future use, broadcast.
They’re checking: That you remember AWS reserves 5, not the textbook 2.
Q.What actually makes a subnet “public”?
A.One route: 0.0.0.0/0 → Internet Gateway in its route table. Remove it and the same subnet is private.
- It’s a routing decision, not a property of the subnet.
- Instances also need a public IP to actually be reachable.
They’re checking: That you know “public” is routing, not a checkbox on the subnet.
Q.Security Group vs NACL, the core difference?
A.SGs are stateful and per-instance; NACLs are stateless and per-subnet. Use SGs primarily.
They’re checking: That you lead with SGs and know NACLs need explicit return traffic.
Q.Can you change a VPC’s CIDR later?
A.Not the primary CIDR, but you can add secondary CIDR blocks to grow the VPC.
- So pick a roomy primary range (a /16) up front.
- Subnets can’t be resized either, plan the carve-up before you build.
They’re checking: That you plan addressing up front because the primary CIDR is fixed.
Your turn, build a VPC from scratch
VPCs, subnets, route tables, and an internet gateway are all free. Build the layout by hand once and it stops being abstract.
Now do it in your own account
As your IAM admin user, build the VPC layout by hand once and it stops being abstract. The scaffolding is free, only what you launch inside it costs.
Before you start
3 to have readyYour IAM admin user from Lesson 1.
AWS CLI v2 signed in.
aws sts get-caller-identityTwo availability zones in your region for the subnets.
aws ec2 describe-availability-zones --query "AvailabilityZones[].ZoneName"- 1
Create a VPC with a 10.0.0.0/16 CIDR.
Free tierYour terminal
You should see: a VpcId; the /16 gives you ~65,000 addresses to carve up.
- 2
Create a public subnet (10.0.0.0/24) and a private subnet (10.0.1.0/24), ideally in two AZs.
Free tierYour terminal
aws cli
AWS docs: create-subnet$ aws ec2 create-subnet --vpc-id <vpc-id> --cidr-block 10.0.0.0/24 --availability-zone <az>You should see: SubnetIds for each; they’re identical until routing makes one public.
- 3
Create and attach an Internet Gateway to the VPC.
Free tierYour terminal
You should see: an InternetGatewayId, then attached to the VPC.
- 4
Add 0.0.0.0/0 → IGW to the public subnet’s route table only.
Free tierYour terminal
aws cli
AWS docs: create-route$ aws ec2 create-route --route-table-id <rtb-id> --destination-cidr-block 0.0.0.0/0 --gateway-id <igw-id>You should see: the public RT has 0.0.0.0/0 → igw; the private RT does not. That one route is the whole difference.
Last step: tear it down
Once you’ve seen it work, remove everything so nothing keeps billing.
VPCs, subnets, route tables, and IGWs are free, but tidy up to keep the console clean.
Delete in reverse: detach + delete the IGW, delete subnets and custom route tables, then the VPC.
Delete the VPC last, after its dependencies.
aws ec2 delete-vpc --vpc-id <vpc-id>Launched anything inside (an instance, a NAT gateway)? Delete that first, NAT especially bills hourly.
Next up
Next, Connecting VPCs
VPC peering, Transit Gateway, Site-to-Site VPN, PrivateLink, and VPC Lattice, how separate networks join up, and which one to reach for.