VPC, a core AWS networking service.
For further understanding of this section, you may want to read a comprehensive article by the AWS Study Group on networking in AWS: Article 3: AWS Networking Services - Part 1: VPC Concepts.
In this section, we’ll create a VPC with 6 subnets (3 private and 3 public distributed across 3 availability zones in the Singapore region), 1 Internet Gateway, and 1 Route Table.
Create VPC
# network
vpc_cidr=10.1.0.0/16
vpc_name=$project-vpc
# Create VPC and Enable DNS hostname feature
vpc_id=$(aws ec2 create-vpc \
--cidr-block $vpc_cidr \
--region $region \
--tag-specifications `echo 'ResourceType=vpc,Tags=[{Key=Name,Value='$vpc_name'},'$tagspec` \
--output text \
--query 'Vpc.VpcId')
aws ec2 modify-vpc-attribute \
--vpc-id $vpc_id \
--enable-dns-hostnames '{"Value": true}'
echo vpc_id=$vpc_id
Create Subnets
Create 6 subnets, including 3 private and 3 public subnets distributed across 3 AZs (a, b, c) in the Singapore region (ap-southeast-1
).
Create Public Subnets
for (( i=1; i<=3; i++ ))
do
eval pubsubnet${i}_cidr=\"10.1.$((($i-1)*16)).0/20\"
done
echo pubsubnet1_cidr=$pubsubnet1_cidr
echo pubsubnet2_cidr=$pubsubnet2_cidr
echo pubsubnet3_cidr=$pubsubnet3_cidr
pubsubnet1_name=$project-pubsubnet-$az_01
pubsubnet2_name=$project-pubsubnet-$az_02
pubsubnet3_name=$project-pubsubnet-$az_03
# Create public subnets
subnet_public_1=$(aws ec2 create-subnet \
--availability-zone $az_01 \
--cidr-block $pubsubnet1_cidr \
--tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$pubsubnet1_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
subnet_public_2=$(aws ec2 create-subnet \
--availability-zone $az_02 \
--cidr-block $pubsubnet2_cidr \
--tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$pubsubnet2_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
subnet_public_3=$(aws ec2 create-subnet \
--availability-zone $az_03 \
--cidr-block $pubsubnet3_cidr \
--tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$pubsubnet3_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
echo subnet_public_1=$subnet_public_1
echo subnet_public_2=$subnet_public_2
echo subnet_public_3=$subnet_public_3
Create Private Subnets
for (( i=1; i<=3; i++ ))
do
eval prisubnet${i}_cidr=\"10.1.$((($i+3)*16)).0/20\"
done
echo prisubnet1_cidr=$prisubnet1_cidr
echo prisubnet2_cidr=$prisubnet2_cidr
echo prisubnet3_cidr=$prisubnet3_cidr
prisubnet1_name=$project-prisubnet-$az_01
prisubnet2_name=$project-prisubnet-$az_02
prisubnet3_name=$project-prisubnet-$az_03
# Create private subnets
subnet_private_1=$(aws ec2 create-subnet \
--availability-zone $az_01 \
--cidr-block $prisubnet1_cidr \
--tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$prisubnet1_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
subnet_private_2=$(aws ec2 create-subnet \
--availability-zone $az_02 \
--cidr-block $prisubnet2_cidr \
--tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$prisubnet2_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
subnet_private_3=$(aws ec2 create-subnet \
--availability-zone $az_03 \
--cidr-block $prisubnet3_cidr \
--tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$prisubnet3_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
echo subnet_private_1=$subnet_private_1
echo subnet_private_2=$subnet_private_2
echo subnet_private_3=$subnet_private_3
Create Internet Gateway
Components in the network needing Internet access must pass through an Internet Gateway. The following commands help create an Internet Gateway and attach it to the previously created VPC:
igw_name=$project-igw
# Create Internet Gateway
gateway_id=$(aws ec2 create-internet-gateway \
--region $region \
--tag-specifications `echo 'ResourceType=internet-gateway,Tags=[{Key=Name,Value='$igw_name'},'$tagspec` \
--output text \
--query 'InternetGateway.InternetGatewayId')
aws ec2 attach-internet-gateway \
--vpc-id $vpc_id \
--internet-gateway-id $gateway_id
echo gateway_id=$gateway_id
Create Route Table and Routing
In the previous step, we created 3 Public Subnets, but currently, these Public Subnets cannot connect to the internet. To make these Public Subnets truly public, they need to be connected to the Internet Gateway through a Route Table.
So, where is the Route Table for private subnets? At this point, private subnets will use the default Route Table provided by AWS. But what if we don’t want to use the Default Route Table? In that case, we need to create a new Route Table.
Create Public Route Table
The following commands help the public subnets connect to the internet gateway. There are 3 main commands involved:
aws ec2 create-route-table
: Create Route Tableaws ec2 create-route
: Connect Route Table to Internet Gatewayaws ec2 associate-route-table
: Connect Route Table to Subnetsrtb_name=$project-rtb-public
# Create Route table
rtb_public_id=$(aws ec2 create-route-table \
--tag-specifications `echo 'ResourceType=route-table,Tags=[{Key=Name,Value='$rtb_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.RouteTable.RouteTableId')
aws ec2 create-route \
--route-table-id $rtb_public_id \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $gateway_id
# Associate each Public Subnet with the Route Table
aws ec2 associate-route-table \
--subnet-id $subnet_public_1 \
--route-table-id $rtb_public_id
aws ec2 associate-route-table \
--subnet-id $subnet_public_2 \
--route-table-id $rtb_public_id
aws ec2 associate-route-table \
--subnet-id $subnet_public_3 \
--route-table-id $rtb_public_id
echo rtb_public_id=$rtb_public_id
Private Route Table
rtb_name=$project-rtb-private
echo rtb_name=$rtb_name
# Create Route table
rtb_private_id=$(aws ec2 create-route-table \
--tag-specifications `echo 'ResourceType=route-table,Tags=[{Key=Name,Value='$rtb_name'},'$tagspec` \
--vpc-id $vpc_id | jq -r '.RouteTable.RouteTableId')
# Associate each Private Subnet with the Route Table
aws ec2 associate-route-table \
--subnet-id $subnet_private_1 \
--route-table-id $rtb_private_id
aws ec2 associate-route-table \
--subnet-id $subnet_private_2 \
--route-table-id $rtb_private_id
aws ec2 associate-route-table \
--subnet-id $subnet_private_3 \
--route-table-id $rtb_private_id
echo rtb_private_id=$rtb_private_id
Create VPC
Check the created VPC using the AWS console
Create Subnets
Create Public Subnet
Check the created public subnets using the AWS Console
Create Private Subnet
Check the created private subnet using the AWS Console
Create Internet Gateway
Check the created Internet Gateway using the AWS Console
Create Route Table and Routing
Create Public Routable
Check the created public Route Table using the AWS Console
Private Route Table
Check the created private Route Table using the AWS Console