Last updated on Apr 6, 2024
14 Min read

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.

AWS cloud architecture for the web application

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

  1. Creating the VPC and Subnets
  2. Launching EC2 instances
  3. Connecting the web-server to the Internet
  4. Using security groups
  5. Using network ACLs
  6. 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.

  1. Log in to the AWS console and select Oregon as the region from the top menu.

  2. Select VPC from the Services menu to go to the VPC console.

  3. Click on the Create VPC button on the top right.

  4. Type in the name as web-app-vpc. In the IPv4 CIDR enter 10.0.100.0/24 and click on Create 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.

  1. In the VPC console, click on Subnets in the left navigation menu. Click on the Create subnets button at the top right.

  2. Select web-app-vpc for the VPC ID.

  3. Type in web-server-subnet for Subnet name.

  4. Select the us-west-2a availability zone.

  5. Fill in 10.0.100.0/28 as the Subnet CIDR.

  6. 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. The two subnets in VPC

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

  1. Select EC2 from the Services menu to go to the EC2 console.

  2. Click on the Key Pairs in the Network & security section in the left navigation menu.

  3. Click on Create key pair on the upper right. Type in a name, leave the default values in other parameters, and click on the Create key pair button at the bottom.

  4. 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

  1. Select EC2 from the Services menu in the EC2 console.

  2. Click on the Instances in the left navigation menu.

  3. Click on Launch instance in the upper right. Type in the name as web-server. Select Ubuntu as the image. Select t2.micro as the instance type. Select the Key pair that we just created.

  4. Click Edit in Network settings. Select web-app-vpc as the VPC and select subnet web-server-subnet.

  5. Select Enable for Auto assign public IP since the web server needs a public IP address.

  6. Click on the Create security group option and type in web-server-sg as the name.

  7. 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.

  1. Select db-server-subnet as the subnet.

  2. Set Auto assign public IP as Disable since we do not want the db-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.

The two EC2 in two subnets.

Step#3: Connecting the web-server to the Internet

Click on the web-server instance and check the public IP address assigned to it.

Public IP address of EC2

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

  1. Select VPC from the Services menu to go to the VPC console.

  2. Click on Internet gateways in the left navigation menu. Click on the Create internet gateway button on the top right.

  3. Type in the name as web-app-internet-gateway and click on the Create internet gateway button at the bottom.

  4. 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 the web-app-internet-gateway by clicking on the check box. Click on the Actions drop-down menu and click on Attach to VPC. From the available VPCs, select the web-app-vpc and click Attach 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.

  1. In the VPC console, click on Route tables in the left navigation menu. Click on the Create route table button in the upper right.

  2. Type in the name as web-server-route-table and select VPC web-app-vpc from the drop-down list.

  3. 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.

  4. In the Routes section of the new Route table, click on Edit routes.
  5. Click on Add route. Type in 0.0.0.0/0 in the Destination field. In the Target field, select Internet Gateway and then select web-app-internet-gateway from the drop-down list.

  6. 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.

  1. In the VPC dashboard click on Subnets in the left navigation menu.

  2. Click on the web-server-subnet. Click on the Route table tab below the subnet details. Click on Edit route table association.
  3. Select web-server-route-table from the drop-down list and click on Save.

Our cloud infra looks like this now. Public vs private subnet

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.

  1. In the EC2 console click on the Security groups in the left-navigation menu and click on the web-server-sg security group.

  2. In the Inbound rules tab inside the web-server-sg click on Edit inbound rules.

  3. Click on the Add rule button to add a new rule. Select All ICMP - IPv4 in the Type field and in the Source field select Anywhere-IPv4. Click on Save 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.

  1. Select Network ACLs from the left navigation menu in the VPC console

  2. Click on Create network ACL. Type in web-server-acl for the name and select web-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.

  3. Click Edit inbound rules in the Inbound rules tab.

  4. Click on Add new rule. Type in the rule number 100. Select HTTPS for type. Type in 0.0.0.0/0 for the source. Select Allow for the Allow/Deny.

  5. Add two more rules to allow SSH and ICMP, and click on Save changes.

  6. 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.

  1. When creating a Key pair for the EC2, we downloaded the private key. Copy it to ~/.ssh/keys/my-key.pem.

  2. Adjust the file permission.
    $ chmod 600 .ssh/my_keys/my-key.pem
    
  3. 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.