Skip to main content

How to design a VPC with public and private subnets on AWS

Design a resilient AWS VPC with public and private subnets across AZs, an internet gateway, and a NAT gateway using Terraform. Covers routing and validation.

Difficulty
Intermediate
Duration
50 minutes
Steps
6

A Virtual Private Cloud (VPC) is your isolated network in AWS. A sound layout separates public subnets (resources that need inbound internet, like load balancers) from private subnets (databases and app servers). Private subnets reach the internet outbound through a NAT gateway, never directly.

Prerequisites

  • An AWS account and Terraform installed.
  • Familiarity with CIDR notation.

Steps

1. Define the VPC

resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
}

A /16 gives 65,536 addresses, ample room to carve subnets.

2. Create subnets

Spread subnets across at least two Availability Zones for resilience:

resource "aws_subnet" "public_a" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true
}
resource "aws_subnet" "private_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.11.0/24"
  availability_zone = "us-east-1a"
}

Repeat for a second AZ.

3. Add an internet gateway

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
}

4. Add a NAT gateway

A NAT gateway lives in a public subnet and needs an Elastic IP:

resource "aws_eip" "nat" { domain = "vpc" }
resource "aws_nat_gateway" "nat" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public_a.id
}

5. Configure route tables

Public subnets route 0.0.0.0/0 to the internet gateway; private subnets route it to the NAT gateway. Associate each route table with its subnets.

6. Apply and validate

terraform init && terraform apply

Verification

Launch a test instance in a private subnet and confirm it can curl https://example.com outbound (via NAT) but has no public IP. Confirm a public-subnet instance is reachable from the internet on its assigned ports.

Next Steps

Add VPC endpoints for S3 and DynamoDB to avoid NAT charges, enable VPC Flow Logs, and segment with security groups and network ACLs.

Prerequisites

  • AWS account
  • Terraform installed
  • Basic networking knowledge

Steps

  • 1
    Define the VPC
  • 2
    Create subnets
  • 3
    Add an internet gateway
  • 4
    Add a NAT gateway
  • 5
    Configure route tables
  • 6
    Apply and validate