← All posts
2 min read

VPC from Zero: networking pieces by command

#aws#vpc#networking#cli
📑 On this page

Part 9 of AWS from Zero. VPC is the network layer where many AWS services live.

If EC2 is a virtual machine, VPC is the private network around it.

The mental model

A basic public VPC needs:

  • VPC: the network boundary.
  • Subnet: a slice of IP addresses inside one Availability Zone.
  • Internet gateway: a door to the internet.
  • Route table: rules that say where traffic goes.
  • Security group: instance-level firewall.

The CLI makes this visible because each piece has its own command.

Create a VPC

REGION="ap-south-1"
VPC_CIDR="10.42.0.0/16"
SUBNET_CIDR="10.42.1.0/24"
VPC_ID=$(aws ec2 create-vpc \
  --region "$REGION" \
  --cidr-block "$VPC_CIDR" \
  --tag-specifications "ResourceType=vpc,Tags=[{Key=Project,Value=aws-from-zero},{Key=Name,Value=aws-zero-vpc}]" \
  --query "Vpc.VpcId" \
  --output text)

Enable DNS hostnames:

aws ec2 modify-vpc-attribute \
  --region "$REGION" \
  --vpc-id "$VPC_ID" \
  --enable-dns-hostnames

Create a subnet

Pick one Availability Zone:

AZ=$(aws ec2 describe-availability-zones \
  --region "$REGION" \
  --query "AvailabilityZones[0].ZoneName" \
  --output text)

Create the subnet:

SUBNET_ID=$(aws ec2 create-subnet \
  --region "$REGION" \
  --vpc-id "$VPC_ID" \
  --cidr-block "$SUBNET_CIDR" \
  --availability-zone "$AZ" \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Project,Value=aws-from-zero},{Key=Name,Value=aws-zero-public-subnet}]" \
  --query "Subnet.SubnetId" \
  --output text)

Make launched instances get public IPs by default:

aws ec2 modify-subnet-attribute \
  --region "$REGION" \
  --subnet-id "$SUBNET_ID" \
  --map-public-ip-on-launch

Add internet access

Create and attach an internet gateway:

IGW_ID=$(aws ec2 create-internet-gateway \
  --region "$REGION" \
  --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=Project,Value=aws-from-zero},{Key=Name,Value=aws-zero-igw}]" \
  --query "InternetGateway.InternetGatewayId" \
  --output text)
aws ec2 attach-internet-gateway \
  --region "$REGION" \
  --internet-gateway-id "$IGW_ID" \
  --vpc-id "$VPC_ID"

Create a route table:

RTB_ID=$(aws ec2 create-route-table \
  --region "$REGION" \
  --vpc-id "$VPC_ID" \
  --tag-specifications "ResourceType=route-table,Tags=[{Key=Project,Value=aws-from-zero},{Key=Name,Value=aws-zero-public-rt}]" \
  --query "RouteTable.RouteTableId" \
  --output text)

Add a default route:

aws ec2 create-route \
  --region "$REGION" \
  --route-table-id "$RTB_ID" \
  --destination-cidr-block "0.0.0.0/0" \
  --gateway-id "$IGW_ID"

Associate it with the subnet:

ASSOC_ID=$(aws ec2 associate-route-table \
  --region "$REGION" \
  --subnet-id "$SUBNET_ID" \
  --route-table-id "$RTB_ID" \
  --query "AssociationId" \
  --output text)

Cleanup order matters

Networking resources have dependencies. Remove them in reverse:

aws ec2 disassociate-route-table --region "$REGION" --association-id "$ASSOC_ID"
aws ec2 delete-route-table --region "$REGION" --route-table-id "$RTB_ID"
aws ec2 detach-internet-gateway --region "$REGION" --internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID"
aws ec2 delete-internet-gateway --region "$REGION" --internet-gateway-id "$IGW_ID"
aws ec2 delete-subnet --region "$REGION" --subnet-id "$SUBNET_ID"
aws ec2 delete-vpc --region "$REGION" --vpc-id "$VPC_ID"

In part 10, we turn these commands into repeatable automation and map the next AWS services to cover.