Introduction to networking on AWS
In this tutorial, we will build this cloud setup on AWS using networking services and components like VPC, Subnets, Route tables, etc.
This is a typical setup for a simple web application.
The VPC has two EC2 instances in two subnets. The web-server
EC2 instance is in the public subnet and is exposed to the Internet via AWS Internet Gateway. Any user on the Internet can directly communicate to the public IPv4 address of web-server
.
The db-server
EC2 instance is in a private subnet. The db-server
not exposed to the Internet as it’s a security risk to do so.
The web-server
talks to the db-server
via the private IP addresses inside the VPC. Security groups and Network ACLs are configured to block unwanted ports while allowing only the minimum required communication between the Internet, web-server
, and db-server
We will be using EC2 instances compatible with the free tier. Your AWS account will be billed if the free tier has expired. Make sure to delete the created AWS resources after completing the tutorial to avoid overcharging.
Prerequisites
To complete this tutorial, you need to have an AWS account with privileges to create VPC, EC2, and VPC resources like route tables, subnets, etc.
Outline of steps
- Creating the VPC and Subnets
- Launching EC2 instances
- Connecting the
web-server
to the Internet - Using security groups
- Using network ACLs
- Logging in to the web-server
Step#1: Creating the VPC and Subnets
A VPC creates a logical boundary for your cloud resources on AWS.
A VPC is located inside a region but can span across multiple availability zones in the region. When you create an AWS account, a default VPC is created in each of the regions. You can create more VPCs based on requirements.
A VPC must have a private IPv4 CIDR and can have an IPv6 CIDR too. The IPv4 CIDR must be between /16 and /28.
Create new VPC
We are going to build our cloud setup in the Oregon region.
-
Log in to the AWS console and select Oregon as the region from the top menu.
-
Select VPC from the Services menu to go to the VPC console.
-
Click on the
Create VPC
button on the top right. -
Type in the name as
web-app-vpc
. In the IPv4 CIDR enter10.0.100.0/24
and click onCreate VPC
at the bottom of the screen.
Create subnets
Our cloud setup consists of two EC2 instances in two separate subnets. So, let’s create two subnets now.
-
In the VPC console, click on
Subnets
in the left navigation menu. Click on theCreate subnets
button at the top right. -
Select
web-app-vpc
for the VPC ID. -
Type in
web-server-subnet
for Subnet name. -
Select the
us-west-2a
availability zone. -
Fill in
10.0.100.0/28
as the Subnet CIDR. -
Click on the
Create subnet
button at the bottom.
Repeat the same steps and create the second subnet db-server-subnet
using 10.0.100.16/28
as the subnet CIDR.
We have created the two subnets now.
Subnets in the same VPC cannot have overlapping IP addresses.
Step#2: Launching EC2 instances
Before creating the EC2, let’s create the SSH keys.
Create a Key Pair
-
Select
EC2
from the Services menu to go to the EC2 console. -
Click on the
Key Pairs
in the Network & security section in the left navigation menu. -
Click on
Create key pair
on the upper right. Type in a name, leave the default values in other parameters, and click on theCreate key pair
button at the bottom. -
You will be prompted to download the private key. Save the private key in a secure location on your computer. We need this private key later in this tutorial to SSH into the EC2 instances.
Launch EC2 instances
-
Select EC2 from the Services menu in the EC2 console.
-
Click on the
Instances
in the left navigation menu. -
Click on
Launch instance
in the upper right. Type in the name asweb-server
. Select Ubuntu as the image. Selectt2.micro
as the instance type. Select the Key pair that we just created. -
Click
Edit
inNetwork settings
. Selectweb-app-vpc
as the VPC and select subnetweb-server-subnet
. -
Select
Enable
for Auto assign public IP since the web server needs a public IP address. -
Click on the
Create security group
option and type inweb-server-sg
as the name. -
Leave out all other parameters in their default values and click on
Launch instance
at the bottom of the page.
Launch the second EC2 db-server
by repeating the above steps with these two changes.
-
Select
db-server-subnet
as the subnet. -
Set
Auto assign public IP
asDisable
since we do not want thedb-server
to be accessible from the Internet.
An EC2 takes several minutes to boot up. Click on the Instances
in the left navigation menu in the EC2 console to check the status of the EC2 instance we just created.
Step#3: Connecting the web-server to the Internet
Click on the web-server
instance and check the public IP address assigned to it.
The users of our web application must be able to reach this public IP address from the Internet,
Ping the public IP address from the terminal on your computer.
$ ping a.b.c.d
Ping will not be successful. Though we have provisioned a public IP address to the EC2, we have not set up an Internet gateway to route traffic from the Internet to this IP address.
Create Internet Gateway
-
Select VPC from the Services menu to go to the VPC console.
-
Click on
Internet gateways
in the left navigation menu. Click on theCreate internet gateway
button on the top right. -
Type in the name as
web-app-internet-gateway
and click on theCreate internet gateway
button at the bottom. -
Our newly created internet gateway is still not attached to a VPC. Click on
Internet gateways
on the left navigation menu in the VPC console. Select theweb-app-internet-gateway
by clicking on the check box. Click on theActions
drop-down menu and click onAttach to VPC
. From the available VPCs, select theweb-app-vpc
and clickAttach internet gateway
.
Next, we must route traffic to the Internet via this Internet Gateway.
The main route table in VPC
Routing inside a VPC is handled by route tables. A route table defines rules for routing traffic between the resources in the VPC.
When you create a new VPC, a route table known as the main route table
is also created in it. Any new subnet is associated with this main route table by default.
Go to VPC
in the Services menu and click on Route tables
in the left navigation menu. Click on the route table attached to the VPC web-app-vpc
.
Click on the Subnet associations
tab. Both the web-server-subnet
and the db-server-subnet
are associated with the main route table.
Click on the Routes
tab. The route table has only one entry for the IP CIDR of the VPC with the target local
. This is the route for all resources inside the VPC.
Create a new route table
We can add a route to the Internet on the main route table
. But we want Internet access only for the web-server
. We do not want to expose the db-server
to the Internet.
So let’s create a new route table for the web-server
.
-
In the VPC console, click on
Route tables
in the left navigation menu. Click on theCreate route table
button in the upper right. -
Type in the name as
web-server-route-table
and select VPCweb-app-vpc
from the drop-down list. -
Click on the
Create route table
button at the bottom. A new route table will be created with one route configured for the VPC IP CIDR block. - In the Routes section of the new Route table, click on
Edit routes
. -
Click on
Add route
. Type in0.0.0.0/0
in theDestination
field. In theTarget
field, selectInternet Gateway
and then selectweb-app-internet-gateway
from the drop-down list. - Click on
Save changes
at the lower right.
Associate a subnet with a route table
Our new route table is still not associated with a subnet. We must configure the web-server-subnet
to use this new route table.
-
In the VPC dashboard click on
Subnets
in the left navigation menu. - Click on the
web-server-subnet
. Click on theRoute table
tab below the subnet details. Click onEdit route table association
. - Select
web-server-route-table
from the drop-down list and click onSave
.
Our cloud infra looks like this now.
Public vs private subnet
A subnet associated with a route table that has a route to an internet gateway is called a public subnet on AWS. The web-server-subnet
is a public subnet now. The IP CIDR of the web-server-subnet
is 10.0.100.0/28
which is a private IP address range. The web-server-subnet
is called public subnet because an EC2 in the subnet can reach the Internet via the Internet gateway.
An EC2 in a public subnet needs to have a public IP address to connect to the Internet via the Internet gateway. If the EC2 does not have a public IP address it cannot reach the Internet even though it’s in a public subnet.
Let’s try to ping
the public IP of web-server
EC2 from our computer.
$ ping a.b.c.d
Still, you will not be able to ping.
Step#4: Using security groups
A Security group is a stateful packet filtering firewall that can be configured for EC2 and some other VPC components.
We cannot Ping the public IP of our EC2 because ICMP is blocked by the security group configured in the web-server
.
Allow ICMP to web-server
When creating web-server
EC2 we created a new security group web-server-sg
. A security group blocks all traffic by default. You must define rules to allow specific traffic. Let’s allow ICMP in this security group.
-
In the EC2 console click on the
Security groups
in the left-navigation menu and click on theweb-server-sg
security group. -
In the
Inbound rules
tab inside theweb-server-sg
click onEdit inbound rules
. -
Click on the
Add rule
button to add a new rule. SelectAll ICMP - IPv4
in the Type field and in the Source field selectAnywhere-IPv4
. Click onSave rules
. Since security groups are stateful we do not need to add a separate outbound rule.
From the terminal in your computer try to Ping the public IP address of the web-server
again. The ping
will be successful now.
$ ping a.b.c.d
Allow HTTPS traffic to web-server
The web-server
EC2 must be allowed to receive HTTPS traffic.
Follow the same procedure above and add a new rule. Use HTTPS
in the Type field to allow HTTPS traffic.
Allow database traffic to db-server
The db-server
does not need to receive traffic from the Internet. But our web-server
will be talking to the db-server
over the protocol of the database software. The port for this communication depends on the database you intend to use. Let’s allow TCP 5432 assuming it’s a PostgreSQL database.
Similar to the web-server-sg
update the rules in the db-server-sg
to allow this communication.
Step#5: Using network ACLs
A network ACL is a stateless packet filtering mechanism in subnets. When creating the subnets we did not explicitly create a new ACL. So our subnets are associated with the default ACL in the VPC.
Let’s check the filtering rules in this default ACL.
In the Services menu, select VPC. Click on the Network ACLs
in the left navigation menu. Click on the network ACL belonging to the web-server-vpc
. Check the tabs Inbound rules
and Outbound rules
.
An ACL has two default rules that block all inbound and outbound traffic respectively. These rules are numbered as *
.
The default ACL is configured with two higher-priority rules to allow all inbound and outbound traffic.
The rules in an ACL are ordered by Rule number
. The rules with higher numbers have lower priority and *
has the lowest priority. When a rule is matched, the ACL applies the rule and ignores all lower-priority rules.
Create a new ACL for web-server
Let’s create a new ACL web-server
and allow only the SSH, HTTPS, and ICMP traffic to EC2 in the web-server
subnet.
-
Select Network ACLs from the left navigation menu in the VPC console
-
Click on
Create network ACL
. Type inweb-server-acl
for the name and selectweb-app-vpc
from the drop-down list. Click on Create network ACL at the bottom. An ACL blocks all traffic both ways by default. So, let’s add specific rules to allow HTTPS, SSH, and ICMP traffic. -
Click
Edit inbound rules
in the Inbound rules tab. -
Click on
Add new rule
. Type in the rule number100
. Select HTTPS fortype
. Type in0.0.0.0/0
for the source. SelectAllow
for theAllow/Deny
. -
Add two more rules to allow SSH and ICMP, and click on
Save changes
. -
Since an ACL is stateless we need to add explicit outbound rules. Edit the outbound rules and add a rule that allows all traffic to
0.0.0.0/0
.
Associate the ACL with the subnet
In the VPC console, click on Network ACLs in the left navigation menu and click on web-server
ACL. Click on Subnet association. Currently, this ACL is not associated with any subnet.
Click on Edit subnet association
. Check the web-server-subnet
from the list of subnets. A subnet can be associated with only one ACL. So, the previous association would be removed when we create the new association.
Create a new ACL for db-server
Follow the same procedure above and create db-server-acl
for the db-server
subnet and update the rules to allow traffic as below.
-
Inbound - Allow PostgreSQL port, SSH, and ICMP from the IPv4 block used in the
web-server-subnet
. -
Outbound - Allow all traffic to IPv4 block used in the
web-server-subnet
.
Step#6: Log in to EC2 with SSH
Login to the web-server
With the SSH port allowed in both the security group and the network ACL, we can now connect to web-server
from the Internet because the web-server
EC2 is in a public subnet.
-
When creating a Key pair for the EC2, we downloaded the private key. Copy it to
~/.ssh/keys/my-key.pem
. - Adjust the file permission.
$ chmod 600 .ssh/my_keys/my-key.pem
- SSH to the public IP address of the
web-server
.$ ssh ubuntu@a.b.c.d -i .ssh/my_keys/my-key.pem
If you are on Windows, use WSL.
Login to db-server
We cannot log into the db-server
directly because it’s not it a public subnet.
To connect to db-server
check out this tutorial on how to connect to EC2 in private subnets.
Wrapping up
In this tutorial, we built cloud infra for deploying a simple web application on AWS. In an upcoming tutorial, we will deploy a web application on this cloud infra.