AWS for Platform Engineers›02 · VPC design
Learning Hub / Cloud — OpenStack, AWS & EKS / AWS for Platform Engineers

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.

Foundation → Practitioner
Key wordsVPCCIDR planningsubnetsavailability zonesroute tablesInternet GatewayNAT Gatewaysecurity groupsNACLsVPC endpoints
Internet gateway VPC 10.0.0.0/16 AZ a public subnet ALB, NAT gateway private subnet EKS nodes, pods data subnet RDS, no internet AZ b public subnet ALB, NAT gateway private subnet EKS nodes, pods data subnet RDS, no internet AZ c public subnet ALB, NAT gateway private subnet EKS nodes, pods data subnet RDS, no internet outbound from private subnets goes via the NAT gateway in its AZ
A three-AZ VPC with public, private and data subnets.

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)

  1. 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).
  2. Look at each route table: which subnets reach the Internet Gateway, which reach the NAT Gateway?
  3. 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).
  4. Add an S3 gateway endpoint, and check the route table entry it adds.
  5. Enable VPC Flow Logs for the private subnet and find your instance's traffic.
  6. 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.