AWS Builder Center
AWS Networking from Scratch: VPC, Subnets, CIDR, IP Types, and Linux on EC2

AWS Networking from Scratch: VPC, Subnets, CIDR, IP Types, and Linux on EC2

I remember the first time I opened the AWS VPC console. There were subnets, route tables, internet gateways, NAT gateways, CIDRs, elastic IPs — and I had no idea how any of it connected. It looked like someone had taken a real data center and just... digitized the chaos. So let me walk you through all of it the way I wish someone had walked me through it: in plain language, with real reasoning, not a wall of definitions.

What Even Is a Network?

Before we touch AWS, let's get grounded.
A network is just a group of machines that can talk to each other. At home, your phone, laptop, and TV are all on the same Wi-Fi network. They can reach each other because they live in the same "address space."
On the internet, billions of machines talk to each other using IP addresses — numerical labels that tell traffic where to go. Think of it like postal addresses for computers.
Now AWS gives you the ability to build your own private network inside the cloud. That's what a VPC is.

VPC — Your Private Corner of AWS

VPC stands for Virtual Private Cloud.
When you create a VPC, you're carving out a logically isolated section of the AWS cloud where you control everything: the IP address range, the subnets, the routing, the security rules. Nobody else gets in unless you say so.
Every AWS account comes with a default VPC in each region, already configured with subnets and an internet gateway so you can launch things immediately. But for anything production-grade, you should create your own VPC so you're in full control.
Here's the key thing about a VPC: it lives in a region. If you're in ap-south-1 (Mumbai), your VPC is a Mumbai VPC. It doesn't span across regions automatically.
A VPC lets you:
  • Define your own private IP address range
  • Split that range into subnets across availability zones
  • Control what gets internet access and what doesn't
  • Set firewall rules at both the instance level and subnet level
  • Connect to your on-premises network via VPN or Direct Connect

CIDR — The Language of IP Ranges

Every VPC and subnet is defined using CIDR notation (Classless Inter-Domain Routing). It sounds intimidating. It's not.
CIDR is just a compact way of writing a range of IP addresses.
It looks like this: 10.0.0.0/16
The number after the slash (/16) is called the prefix length. It tells you how many bits are "fixed" (the network part) versus how many bits are "free" (the host part).
IPv4 addresses are 32 bits total. So:
CIDR BlockFixed BitsFree BitsTotal IPsUsable IPs (approx)
/882416,777,216~16.7 million
/16161665,536~65,000
/24248256~254
/282841611
/3232011 (single IP)
When you create a VPC, AWS recommends using a range from the RFC 1918 private address space:
  • 10.0.0.0/8 — largest, supports millions of IPs
  • 172.16.0.0/12
  • 192.168.0.0/16 — common in home networks
For most production VPCs, 10.0.0.0/16 is the go-to. It gives you 65,536 addresses to split into subnets.
Important: AWS reserves 5 IP addresses in every subnet — the first four and the last one — for internal routing, DNS, and future use. So a /24 subnet (256 IPs) gives you 251 usable addresses.

Subnets — Dividing Your VPC

A VPC gives you a big IP range. Subnets let you divide that range into smaller chunks, each associated with a specific Availability Zone (AZ).
Unlike your VPC (which lives in a region), a subnet lives in a single AZ. This is how you achieve high availability — by spreading your resources across multiple subnets in different AZs.
There are two types of subnets that matter in AWS:

Public Subnet

A public subnet has a route to an Internet Gateway (IGW). Resources launched here can have a public IP and communicate directly with the internet.
Use public subnets for: load balancers, bastion hosts, NAT gateways.

Private Subnet

A private subnet has no direct route to the internet. Resources here can't be reached from the internet, and they can't initiate outbound internet connections either — unless you route through a NAT Gateway in a public subnet.
Use private subnets for: application servers, databases, internal services.
A typical 3-tier architecture looks like this:
1
2
3
4
5
6
7
8
9
10
VPC: 10.0.0.0/16
│
├── Public Subnet A (10.0.1.0/24) — AZ-a → Internet Gateway
├── Public Subnet B (10.0.2.0/24) — AZ-b → Internet Gateway
│
├── Private Subnet A (10.0.11.0/24) — AZ-a → NAT Gateway
├── Private Subnet B (10.0.12.0/24) — AZ-b → NAT Gateway
│
├── DB Subnet A (10.0.21.0/24) — AZ-a (no internet access)
└── DB Subnet B (10.0.22.0/24) — AZ-b (no internet access)
Your ALB lives in the public subnets. Your EC2 app servers in the private subnets. Your RDS instances in the DB subnets. Clean, secure, and resilient.

IP Address Types in AWS

When you launch an EC2 instance or any resource in a VPC, you're working with several types of IP addresses. Understanding the difference matters a lot — especially when debugging connectivity issues.

1. Private IP Address

Every EC2 instance gets a private IP from the subnet's CIDR range automatically. This is the IP used for internal communication within your VPC. It stays with the instance as long as it's running and comes back if stopped (for most instance types).
This IP is not reachable from the internet. Period.

2. Public IP Address

If your subnet's "Auto-assign public IPv4" is enabled, or you explicitly enable it at launch, your instance gets a public IP from AWS's pool of public addresses. This IP is dynamically assigned — meaning if you stop and start the instance, you get a different public IP.
Not ideal for production workloads where you need a stable endpoint.

3. Elastic IP (EIP)

An Elastic IP is a static public IPv4 address you own until you release it. You allocate it from AWS and then associate it with an EC2 instance or a network interface.
Unlike the dynamic public IP, your EIP doesn't change when you stop/start the instance. It follows the resource.
One catch: AWS charges you for Elastic IPs that are allocated but not associated with a running instance. So don't let EIPs sit around unattached.
Use EIPs for: NAT gateways, bastion hosts, any resource that needs a fixed public IP.

4. IPv6 Address

AWS supports IPv6. If you enable IPv6 for your VPC and subnet, instances can get a global unicast IPv6 address — which is publicly routable by design (no NAT needed). IPv6 addresses in AWS are /128 (single address per interface).
Not every use case needs IPv6, but it's good to know it exists.

Quick comparison:

TypeRoutableStaticFree?
Private IPWithin VPC onlyPersists while runningYes
Public IPInternetChanges on stop/startYes
Elastic IPInternetPermanentYes (when attached)
IPv6InternetPermanentYes

Route Tables and Gateways

Subnets don't magically know where to send traffic. That's what route tables are for.
A route table is a set of rules (routes) that determine where network traffic is directed. Every subnet must be associated with a route table.
A typical public subnet route table:
DestinationTarget
10.0.0.0/16local
0.0.0.0/0igw-xxxxxxxx
The local route means any traffic destined within the VPC stays inside. The 0.0.0.0/0 route sends everything else to the Internet Gateway — which is what makes the subnet "public."
A private subnet's route table looks like:
DestinationTarget
10.0.0.0/16local
0.0.0.0/0nat-xxxxxxxx
The 0.0.0.0/0 goes to a NAT Gateway (in a public subnet), which allows outbound internet traffic while blocking inbound connections.

Security Groups and NACLs

You've got your VPC, subnets, and routes set up. Now you need to control what traffic actually reaches your instances.
AWS gives you two layers of security:

Security Groups (Stateful)

Security groups act as a virtual firewall at the instance level. They're stateful — if you allow inbound traffic on port 80, the response traffic is automatically allowed out, even if there's no explicit outbound rule.
You define inbound and outbound rules. By default, a new security group blocks all inbound and allows all outbound.
Common setup for a web server:
  • Inbound: port 80 (HTTP) from 0.0.0.0/0
  • Inbound: port 443 (HTTPS) from 0.0.0.0/0
  • Inbound: port 22 (SSH) from your IP only
  • Outbound: all traffic allowed

Network ACLs (Stateless)

NACLs operate at the subnet level and are stateless — you must explicitly allow both inbound and outbound traffic for a connection to work. They also evaluate rules in order by rule number.
For most use cases, security groups are sufficient. NACLs are useful for an extra layer of control, like blocking specific IP ranges at the subnet boundary.

Linux on EC2 — What You Actually Need to Know

When you launch an EC2 instance, you're choosing an AMI (Amazon Machine Image), which includes the OS. For Linux, the most common choices are:
  • Amazon Linux 2023 — AWS's own distribution, optimized for EC2, includes dnf package manager
  • Ubuntu — widely used, huge community, familiar apt package manager
  • RHEL / Rocky Linux — enterprise-grade, dnf/yum
  • Debian — stable, lightweight
For beginners on AWS, Amazon Linux 2023 or Ubuntu 22.04 LTS are the easiest to work with because they have solid community support and AWS-specific tooling pre-installed.

Connecting to Your Linux Instance

When you launch an EC2 instance, you associate a key pair. AWS puts the public key on the instance, and you keep the private key (.pem file). You then SSH in:
bash
1
2
chmod 400 my-key.pem
ssh -i my-key.pem ec2-user@<your-public-ip>
The default user varies by AMI:
  • Amazon Linux: ec2-user
  • Ubuntu: ubuntu
  • RHEL/Rocky: ec2-user or root

Basic Networking Commands on Linux EC2

Once you're inside, these commands help you understand your network configuration:
bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# See your private IP and network interfaces
ip addr show

# Check routing table
ip route

# Test connectivity
ping 8.8.8.8

# Check if a port is open
curl -v telnet://your-db-host:5432

# DNS lookup
nslookup google.com

# Check active connections
ss -tuln

Instance Metadata Service (IMDS)

One thing unique to EC2 Linux instances is the metadata service. From inside any EC2 instance, you can query:
bash
1
2
3
4
5
6
7
8
# Get your instance's private IP
curl http://169.254.169.254/latest/meta-data/local-ipv4

# Get your public IP
curl http://169.254.169.254/latest/meta-data/public-ipv4

# Get your IAM role credentials
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
This is how applications running on EC2 discover their own identity and credentials without hardcoding anything. The IP 169.254.169.254 is a link-local address accessible only from within the instance.

How It All Fits Together

Let's tie it all together with a real-world scenario: you're deploying a web API on EC2.
  1. You create a VPC in ap-south-1 with CIDR 10.0.0.0/16.
  2. You create a public subnet (10.0.1.0/24) in AZ-a and attach an Internet Gateway.
  3. You create a private subnet (10.0.11.0/24) in AZ-a with a NAT Gateway for outbound internet (package installs, API calls).
  4. You launch your EC2 instance running Ubuntu 22.04 in the private subnet. It gets a private IP (10.0.11.45).
  5. You create a security group allowing port 443 from your load balancer's security group, and port 22 from a bastion host.
  6. You put an Application Load Balancer in the public subnet, which receives internet traffic and forwards it to your EC2 instance.
  7. You assign an Elastic IP to your NAT Gateway so outbound traffic from your private subnet has a stable source IP (useful for third-party IP whitelisting).
Your application is now:
  • Not directly reachable from the internet (private subnet)
  • Able to make outbound calls (NAT Gateway)
  • Accessible to users via HTTPS through the ALB (public subnet)
  • Protected by security groups and optionally NACLs

Common Mistakes to Avoid

1. Launching everything in the default VPC. The default VPC is auto-assigned public IPs and internet access for all subnets. Fine for testing, wrong for production.
2. Using /16 for every subnet. Plan your CIDR ranges carefully. Once you create a subnet, you can't resize it. Sketch your network before you build it.
3. Forgetting AWS reserves 5 IPs per subnet. A /28 gives you 16 IPs minus 5 = 11 usable. Don't get caught short in small subnets.
4. Leaving unused Elastic IPs allocated. AWS charges ~$0.005/hour for EIPs not attached to a running instance. They add up.
5. Security groups vs NACLs confusion. If traffic isn't flowing and your SG looks right, check your NACL. NACLs are stateless — you need both inbound and outbound rules.
6. SSH on port 22 open to 0.0.0.0/0. Restrict SSH to your own IP or use AWS Systems Manager Session Manager to avoid opening port 22 entirely.

Final Thoughts

Networking in AWS isn't magic. It's your VPC defining the boundary, CIDR blocks carving up the address space, subnets placing resources in specific AZs, route tables directing traffic, and security groups/NACLs deciding what's allowed through.
Once you've built a 3-tier VPC by hand — public, private, and DB subnets, IGW, NAT Gateway, route tables, and security groups — it clicks. And then when you start automating it with Terraform or CloudFormation, you're not guessing at what the code is doing, because you've done it yourself.
That hands-on understanding is what separates someone who passed an exam from someone who can actually debug a production network issue at midnight.
Build it. Break it. Fix it. That's the pathway.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article