AWS basics · Lesson 3 · 40 min

VPC: your own network in the cloud

Before you launch a server, it needs somewhere to live: a network with addresses, a way in from the internet (or deliberately none), and a firewall. In AWS that's a VPC (Virtual Private Cloud). It's the same networking you learned on Linux: CIDR blocks, routes, a default gateway and firewall rules. The difference is that you build it with API calls instead of cables.

You will learn

  • VPCs, CIDR blocks and subnets, and why a subnet lives in one AZ
  • What makes a subnet public: an internet gateway plus a route table
  • Security groups (stateful, per instance) vs network ACLs (stateless, per subnet)
  • Building a small VPC from the CLI, with shell variables holding the IDs

The pieces

VPC cht-vpc  10.0.0.0/16 ─────────────────────────────────────────── us-east-1
│
├── Internet gateway (igw-…) ◀──── the internet
│
├── Route table "public-rt":   10.0.0.0/16 → local      0.0.0.0/0 → igw-…
│      │
│      └── Subnet public-a   10.0.1.0/24   us-east-1a   ← web servers get public IPs
│
└── Main route table:          10.0.0.0/16 → local      (no way out)
       └── Subnet private-b  10.0.2.0/24   us-east-1b   ← databases: no internet route
PieceWhat it doesLinux cousin
VPCA private network in one region, with an address range like 10.0.0.0/16 (65,536 addresses)your home LAN
SubnetA slice of the VPC's range, in one availability zone. /24 = 256 addresses, of which AWS keeps 5one network segment
Internet gatewayThe VPC's door to the internet. Free, and does nothing until a route points at ityour router's WAN port
Route tableRules for where packets go, attached to subnetsip route
Security groupA firewall around each instance: allow rules only. Stateful: replies to allowed traffic go out on their ownfirewalld / ufw on every server
Network ACLA firewall on the subnet edge, with numbered allow and deny rules. Stateless: you must allow replies too. Most people leave the default (allow all)a router ACL

A subnet is public only because its route table sends 0.0.0.0/0 to an internet gateway. There's no "public" checkbox. Private subnets have no such route, so nothing there can be reached from the internet, even if it has a public IP.

Every region already has a default VPC

AWS makes one (172.31.0.0/16) with a public subnet in each AZ, so beginners can launch servers straight away. It's fine for experiments. For real work you build your own, so you know exactly what's public.

Planning the addresses

Pick a private range (10.x, 172.16–31.x or 192.168.x) that won't clash with your office or other VPCs you might connect later. A common plan: a /16 for the VPC, and a /24 per subnet, numbered so you can tell them apart: 10.0.1.0/24 public in AZ a, 10.0.2.0/24 in AZ b, and so on. Subnets can't overlap, and they must fit inside the VPC's range. AWS will refuse if they don't.

Building it from the CLI

Each create command prints JSON with a new ID in it. Catch the ID in a shell variable with --query … --output text, and the next command can use it:

VPC=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=cht-vpc}]' \
  --query Vpc.VpcId --output text)
echo $VPC                                  # vpc-0e64304f81f7eef46

SUBA=$(aws ec2 create-subnet --vpc-id $VPC --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a --query Subnet.SubnetId --output text)

IGW=$(aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text)
aws ec2 attach-internet-gateway --internet-gateway-id $IGW --vpc-id $VPC

RTB=$(aws ec2 create-route-table --vpc-id $VPC --query RouteTable.RouteTableId --output text)
aws ec2 create-route --route-table-id $RTB --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW
aws ec2 associate-route-table --route-table-id $RTB --subnet-id $SUBA
aws ec2 modify-subnet-attribute --subnet-id $SUBA --map-public-ip-on-launch   # new servers here get a public IP

Tags are labels (Key=Name,Value=cht-vpc). The Name tag is what the web console shows, and tags like Project=cht let you find (and clean up) everything that belongs together.

Security groups

SG=$(aws ec2 create-security-group --group-name web-sg --description "Web servers" \
  --vpc-id $VPC --query GroupId --output text)
curl checkip.amazonaws.com                    # your public IP, e.g. 203.0.113.77
aws ec2 authorize-security-group-ingress --group-id $SG --protocol tcp --port 22 --cidr 203.0.113.77/32
aws ec2 authorize-security-group-ingress --group-id $SG --protocol tcp --port 80 --cidr 0.0.0.0/0

SSH only from your address (/32 = exactly one IP), the website from anywhere (0.0.0.0/0). A security group can also allow traffic from another security group (--source-group), which is how you'll let a load balancer talk to web servers in the load balancer lesson.

Never open port 22 to 0.0.0.0/0

Bots try passwords on every public SSH port within minutes of it appearing. Allow your own IP only, or skip SSH completely and use AWS Systems Manager Session Manager.

Timeout or refused?

Just like on Linux: a security group that doesn't allow a port drops the packets, so you see a timeout. If the packet gets through but nothing listens there, you get connection refused. Timeout = check the network (security group, route table). Refused = check the server.

One piece this lesson leaves out: a NAT gateway lets servers in private subnets reach out to the internet (for updates) without being reachable. It's handy but costs about $32 a month plus data, even when idle. Beginners often forget one and get a surprise bill.

Practice: build a VPC 🧱

An empty account (just the default VPC). Build the network from the diagram: a VPC, a public and a private subnet, an internet gateway, a route table and a security group. The next lesson launches a server into a network like this one.

Quick check

1. What makes a subnet "public"?

2. curl to your server's port 80 hangs and then times out. What do you check first?

3. Why does each subnet live in exactly one availability zone?

Finished the missions and the quiz? Mark it done to track your progress.