Skip to content

VPC Networking: Subnets, Route Tables & Security Groups

Every AWS architecture sits on top of a VPC — design the subnets, routing, and access controls correctly before anything else.

VPCRoute TablesNAT GatewaySecurity Groups
2 min readIntermediate
Lab time: 30-40 min
RR

Ranjith R

Linux SysAdmin & Cloud Engineer

Published July 1, 2026Updated July 6, 2026
Share
Section 01

Prerequisites

  • An AWS account
  • Basic understanding of IP addressing and CIDR notation (e.g. what /24 means)
Section 02

What You'll Learn

  • Plan a VPC's CIDR range and divide it into public and private subnets across AZs
  • Configure route tables so private subnets reach the internet only through a NAT gateway
  • Explain the difference between security groups (stateful) and NACLs (stateless)
  • Design a 2-tier VPC layout for a real application
Section 03

Theory

A VPC is a logically isolated network you define within a single AWS region, starting from a CIDR block (e.g. 10.0.0.0/16 — 65,536 addresses). Subnets carve that range into smaller blocks, each pinned to exactly one Availability Zone. A subnet is "public" only by convention — specifically, because its route table sends 0.0.0.0/0 traffic to an Internet Gateway; nothing else structurally distinguishes it from a private subnet.

Route tables are the actual mechanism

Every subnet is associated with exactly one route table. A public subnet's route table has a route for 0.0.0.0/0 → igw-xxxx. A private subnet's route table instead sends 0.0.0.0/0 → nat-xxxx (a NAT Gateway sitting in a public subnet), so instances can initiate outbound connections (package updates, API calls) but cannot be reached by unsolicited inbound traffic from the internet.

Security Groups vs. Network ACLs

Security GroupNetwork ACL
Applies toENI (instance level)Subnet level
StateStateful — return traffic auto-allowedStateless — must allow both directions explicitly
RulesAllow onlyAllow and Deny, evaluated in rule-number order
Typical usePrimary day-to-day access controlCoarse subnet-wide backstop
Section 04

Architecture

A standard 2-AZ, 2-tier VPC: public subnets hold the ALB and NAT Gateways, private subnets hold app and database instances

Section 05

Hands-On Lab

# 1. Create the VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query Vpc.VpcId --output text
# => vpc-0abc123

# 2. Create one public and one private subnet
aws ec2 create-subnet --vpc-id vpc-0abc123 --cidr-block 10.0.1.0/24 --availability-zone us-east-1a
aws ec2 create-subnet --vpc-id vpc-0abc123 --cidr-block 10.0.11.0/24 --availability-zone us-east-1a

# 3. Create and attach an Internet Gateway
aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text
aws ec2 attach-internet-gateway --vpc-id vpc-0abc123 --internet-gateway-id igw-0def456

# 4. Create a public route table and route 0.0.0.0/0 to the IGW
aws ec2 create-route-table --vpc-id vpc-0abc123 --query RouteTable.RouteTableId --output text
aws ec2 create-route --route-table-id rtb-0ghi789 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-0def456
aws ec2 associate-route-table --route-table-id rtb-0ghi789 --subnet-id subnet-0public

# 5. Create a NAT Gateway in the public subnet (requires an Elastic IP), then
# route the private subnet's 0.0.0.0/0 traffic to it the same way as step 4
Section 07

Best Practices

Always span at least two Availability Zones

A single-AZ VPC has no protection against an AZ-level outage — mirror every public/private subnet pair into a second AZ from day one, even for small workloads.

Reserve CIDR space for growth

A /16 VPC divided into a handful of /24 subnets still leaves enormous headroom for future subnets (additional tiers, VPC peering ranges) — starting too small forces a disruptive re-IP later.
Section 08

Common Mistakes

Putting a database directly in a public subnet 'for simplicity'

Even with a locked-down security group, a public subnet means the instance has a route to the internet at all — a single misconfigured security group rule then exposes it directly. Databases belong in private subnets, full stop.

One NAT Gateway shared across all AZs

A NAT Gateway lives in one AZ; if every private subnet in every AZ routes through a single NAT Gateway, that AZ's failure takes down outbound connectivity for the whole VPC. Deploy one NAT Gateway per AZ for real high availability (at the cost of running more of them).
Section 09

Troubleshooting

An EC2 instance in a private subnet can't reach the internet: check, in order: the subnet's route table has a 0.0.0.0/0route to a NAT Gateway; the NAT Gateway itself is in a public subnet whose route table points to an IGW; the instance's security group allows the outbound traffic; and the NACL (if customized) allows it in both directions.

Two instances in the same subnet can't reach each other: since they share a route table, this is almost always a security group rule — remember SGs are stateful but still need an explicit inbound allow rule on the receiving instance for the initiating traffic.

Section 10

Interview Questions

Security Groups operate at the instance (ENI) level and are stateful — if you allow inbound traffic on a port, the matching return traffic is automatically allowed out, regardless of outbound rules. Network ACLs operate at the subnet level and are stateless — you must explicitly allow both the inbound request and the outbound response, and rules are evaluated in numbered order with an explicit deny possible (SGs only support Allow rules). SGs are the primary tool for day-to-day access control; NACLs are typically used as a coarser subnet-level backstop.
See all 20 AWS interview questions
FAQ

Frequently Asked Questions

No — if instances only need to reach other AWS services, VPC endpoints (Gateway for S3/DynamoDB, Interface/PrivateLink for most others) provide that connectivity without a NAT Gateway at all, and are typically cheaper for that specific traffic.
Section 12

Summary

A subnet is "public" purely because its route table points 0.0.0.0/0 at an Internet Gateway; private subnets route outbound traffic through a NAT Gateway instead. Security groups (stateful, instance-level) handle day-to-day access control, NACLs (stateless, subnet-level) act as a coarser backstop — and every production VPC should span at least two Availability Zones with a NAT Gateway in each.