Lesson 02 of 7 · Modules
VPC design
Design an AWS network that won't box you in later: CIDR planning, public and private subnets across availability zones, routing through Internet and NAT gateways, security groups vs NACLs, and VPC endpoints to cut cost and exposure.
A VPC is your private network in AWS
A VPC is an isolated network with an IP range you choose, spread across availability zones (separate data centres in a region). You carve it into subnets (each in one AZ), and route tables decide where each subnet's traffic goes.
A VPC is your own gated housing estate. Subnets are streets, each in a different neighbourhood (availability zone), so a flood in one doesn't reach the others. Some streets have a gate to the main road (public subnets with an Internet Gateway). Others only have a one-way exit through a guarded gate (private subnets with NAT): residents can go out shopping, but strangers can't come in.
Plan the CIDR first
- Pick a range that won't overlap with on-prem networks, VPNs or other VPCs you may connect (e.g. allocate
/16s per VPC from a company plan). - For EKS with the VPC CNI, pods use VPC IPs too. Size generously, or plan a secondary CIDR (commonly from
100.64.0.0/10) for pods (see Amazon EKS in Production). - AWS reserves 5 addresses per subnet.
A typical three-tier layout
VPC 10.20.0.0/16 (eu-west-1)
├── public-a 10.20.0.0/24 public-b 10.20.1.0/24 public-c 10.20.2.0/24 → IGW (load balancers, NAT)
├── private-a 10.20.16.0/20 private-b 10.20.32.0/20 private-c 10.20.48.0/20 → NAT GW (nodes, pods)
└── data-a 10.20.64.0/24 data-b 10.20.65.0/24 data-c 10.20.66.0/24 → no internet (databases)
Routing
| Subnet type | Default route (0.0.0.0/0) | Used for |
|---|---|---|
| Public | Internet Gateway | Load balancers, NAT gateways, bastions (rare) |
| Private | NAT Gateway (in a public subnet) | Nodes and apps that need outbound internet |
| Isolated | none | Databases, sensitive systems |
Use one NAT Gateway per AZ (with each private subnet routing to the NAT in its own AZ). One shared NAT is cheaper but becomes a single point of failure and adds cross-AZ data charges.
Security groups vs network ACLs
| Security groups | NACLs | |
|---|---|---|
| Attached to | Network interfaces (instances, pods with SG support, LBs) | Subnets |
| State | Stateful (replies allowed automatically) | Stateless (allow return traffic explicitly) |
| Rules | Allow only | Allow and deny, evaluated in order |
| Reference other SGs | ✅ ("allow from sg-app") | ❌ (CIDRs only) |
Do most filtering with security groups that reference each other (web SG → app SG → db SG). Use NACLs sparingly, as a coarse extra layer.
VPC endpoints
| Type | Services | Cost |
|---|---|---|
| Gateway endpoint | S3, DynamoDB | Free (route table entry) |
| Interface endpoint (PrivateLink) | ECR, STS, CloudWatch, Secrets Manager, most others | Hourly + per-GB |
Endpoints keep traffic private and avoid NAT processing charges. For private EKS nodes, the ECR (api + dkr), S3, STS and EC2 endpoints are common.
Try it: build and inspect (sandbox account)
- Create a VPC with 2 public and 2 private subnets in two AZs (the console's "VPC and more" wizard, or Terraform in Terraform & IaC).
- Look at each route table: which subnets reach the Internet Gateway, which reach the NAT Gateway?
- Launch a small instance in a private subnet with SSM Session Manager access (no SSH, no public IP); from it,
curl https://example.com(via NAT). - Add an S3 gateway endpoint, and check the route table entry it adds.
- Enable VPC Flow Logs for the private subnet and find your instance's traffic.
- Delete everything afterwards: NAT Gateways cost money per hour.
Going deeper: networks at scale
- Connect many VPCs with Transit Gateway (hub and spoke) rather than a mesh of peerings; plan route domains per environment.
- Centralise egress (inspection, fixed IPs) in a shared network account when compliance requires it.
- Use IPAM (the AWS VPC IP Address Manager) to allocate non-overlapping CIDRs across accounts.
- Watch data transfer costs: cross-AZ traffic, NAT processing, and internet egress often surprise teams (lesson 07).
Recap
- Plan non-overlapping CIDRs, sized for pods if using EKS.
- Public = route to an IGW; private = route to a NAT GW (one per AZ); isolated = no internet.
- Security groups (stateful, reference each other) do most filtering; NACLs are stateless and coarse.
- VPC endpoints keep AWS traffic private and cut NAT costs.
This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.