In this piece, I will be showing you how to deploy a simple python Flask application with an AWS application load balancer. The flask application will be deployed to two private elastic cloud-compute (EC2) instances. These instances will sit behind the application load balancer(ALB) as it controls which of the instance serves the content of the Flask application.
Since the private instances need access to the internet to download the Flask dependencies, I will be creating public instances to which the Network address translation(NAT) gateway will be attached.
Without further ado, let’s kick-start the deployment process.
To deploy on AWS you must first have an account with AWS. You can click here to create an account. The private and public EC2 instances will be created in our Virtual Private Cloud (VPC) network.
Type “VPC” into the search bar on the AWS website.
Click on the VPC that is displayed by the browser.
Click on “Create VPC”
On the “Create VPC” page, select “VPC and more”. This option helps you to automatically create subnets where the public and private instances will reside.
Fill in the name of the VPC, this will be used to identify your VPC when creating your EC2 instances.
The default CIDR block value is sufficient for your VPC.
Tenancy should be left as “Default”, you will be charged for using “Dedicated”.
The ALB requires a minimum of two Availability Zones(AZ), and in this project, we need just two AZ, so select 2.
We will be needing two public subnets and two private subnets, so select two for “Number of private subnets” and “Number of public subnets”.
You can choose to customize the CIDR values of the subnets.
For the “NAT gateways” and “VPC endpoints“ you can leave them as “None”. We will still create a NAT gateway.
You can untick the “DNS options” options
Click “Create VPC”
Once VPC has been created, the next step is to create route tables(RT) for the public and private subnets. For the public subnets to be reachable from the internet, you will have to attach an Internet gateway to the public RT and a NAT gateway to the private RT. To get more information about route tables, you can take a look at this blog.
In the VPC webpage, the “Route tables” option is in the left sidebar of the page.
Select “Route tables”
Click on “Create route table”.
Remember to select the VPC you created. We will be creating two route tables, so you will have different names. You can use “Private route table” and “Public route table”. Going on we assume these are the name used for the RT.
Click the “Create route table” button.
Repeat this same process for the second RT.
To ensure your “Private route table” has access to the internet, and can be reachable from the internet, we will create an Internet Gateway(IG) and attach it to this RT.
In the VPC webpage, the “Internet Gateway” option is in the left sidebar of the page.
Select “Internet gateways”
Click the “Create internet gateway” button,
On the “Create internet gateway” page, fill in the name you want the IG to be identified as. Let’s assume we call it “my-internet-gateway”.
Click the “Create internet gateway” button.
Once done, we need to attach the created IG to the “Public route table” and also associate the created public subnets with this route table.
To do this:
In the VPC webpage, the “Route tables” option is in the left sidebar of the page.
A table containing the create route tables will be displayed.
Click on the “Route table ID” of “Public route table”.
Scroll down and click the “Edit routes” button.
Click on the “Add route”
On the “Destination” fill in “0.0.0.0/0” and in the “Target” select “Internet Gateway”, the newly created IG i.e “my-internet-gateway” will display, select it.
Click on the “Save changes” button.
Return back to the “Route Tables” page.
Click on the “Route table ID” of “Public route table” again but this time scroll down and select “Subnet associations”
10. Click on the “Edit subnet associations” button.
All four created subnets will be shown here, select only the subnets with “public” in their name. Remember, this RT is for public subnets.
Click the “Save associations” button.
At this point, any EC2 instance placed in any of the two public subnets will have access to the internet and will also be reachable from the internet.
Our next task is to ensure our private subnets have access to the internet. Note, the private subnets will have access to the internet but will not be reachable from the internet. A classic use case of private subnets is to deploy databases. A NAT gateway is used to accomplish that purpose.
For private subnets, A NAT gateway will be created, attached to the created “Private route table” and the private subnets associated with the “Private route table”.
To create a NAT gateway:
In the VPC webpage, the “NAT gateways” is in the left sidebar of the page.
Click on “NAT gateways”
Click on “Create NAT gateway
In the “Create NAT gateway” page, fill in the name for the gateway, lets assume it’s “my-nat-gateway”
For the “Subnet” select any of the created public subnets. NAT gateways are created in public subnets and then attached to a private route table.
“Connectivity type” should be left as “Public” because you want access to the internet.
Click on the “Allocate Elastic IP”. It should be noted that the NAT gateway is not part of the free tier services offered by AWS because you are allocating an elastic IP to the NAT gateway.
Click the “Create NAT gateway” button.
The same steps used to attach the Internet Gateway to the “Public route table” should be used in attaching the NAT gateway to the “Private route table”.
On the “Destination” fill in “0.0.0.0/0” and in the “Target” select “NAT Gateway”, the newly created IG i.e “my-nat-gateway” will display, select it.
In the subnet association for the “Private route table”, only subnets with private in their name should be selected and associated with this route table.
With the steps above, you will have your VPC, subnets, internet gateway, NAT gateway, and route tables ready. Our next task is to create EC2 instances that will reside in the created subnets. We will be creating four instances, two public, and two private instances. I will show guide you step by step on how to create a public and private instance. These steps should then be followed to create the other instances. AWS actually offers a service to automatically create these resources using CloudFormation, but this is beyond the scope of the write-up.
Type “EC2” into the search bar on the AWS website.
Click on the “EC2” that is displayed by the browser.
On the “EC2” page, scroll down and click on “Launch instance”
In the “Launch an instance” page, fill in the name of the instance. Let’s call it “public instance 1”.
For this tutorial, I will be choosing “Ubuntu” AMI, fill free to choose any AMI.
In the “Amazon Machine Image (AMI)” selection drop bar, select any version of your choice but be certain is “free tier eligible”
For the “instance type” I am going with “t2.micro” because it is free.
For the “key pair”, click on “create new key pair”. Input the name you wish to save the key, leave the other option as it is, click “create key pair” and a key pay will be downloaded to your system. This key will be needed when you want to SSH into the instance. Lets call this key name “mykey”, in your system it will be saved as “mykey.pem”
In the “Network settings” option, click on the “Edit” button.
In the VPC, click and select the VPC we created earlier.
In the subnet, select the subnet with “Public and 1” in its name.
“Auto-assign public IP” should be set to “enable” because this is a public instance.
Leave the selection on “Create security group”
In the “Security group name”, input whatever name you want. You will be using this security group(SG) for the other instances too. Let’s call it “test-SG”.
Allow ssh, to add another rule, click on the “Add security group rule” button. For “Type”, click and select “HTTP”, for “Source type”, click and select “Anywhere”, for the “source” input “0.0.0.0/0”. Allowing “HTTP” allows internet access.
The following configuration is sufficient for the “public instance 1”. Click on the “Launch instance” button.
In step 4 for the creation of a public instance, change the name to “private instance 1”.
In step 8, you don’t need to create another “key par”, click on the “Key pair name - required” drop-down and select the key you created previously.
In step 11, select the subnet with “private and 1” in its name.
In step 12, “Auto-assign public IP” should be set to “disable”
In step 14 and 15, you don’t need to create a new security group, choose “Select existing security group” and select “test-SG” which is our created SG.
Click on the “Launch instance” button.
For the second public and private instance, the steps above should be followed, what needs to change is the name of the instances which will be “public instance 2” and “private instance 2” and the subnets which will be subnets that contain “Public and 2” and “Private and 2” in its name respectively.
On the EC2 page, click on “Instances (running)”
You will be directed to a webpage, that has a table showing all our running instances. I will assume you followed the above steps to create your VPC. You should have something like this.
Click on the “Instance ID” of “public instance 1”.
Click on the “Connect” button.
In the “Connect to instance” page, click on “connect”
A new browser tab will open, it is a console for public instance 1”. You should have something like this.
To connect to your private instance from the public instance using SSH, you will need to ensure you have the created key pair, i.e “mykey.pem” stored in this public instance.
From your “public instance 1” console run this command to create the key file.
sudo touch mykey.pem
Copy the content of “mykey.pem” file in your local system, open the created “mykey.pem” file in your “public instance 1” and paste the content into this file and save. You can choose the use vi
or nano
for this file editing.
The key is now in your “public instance 1”. You can run the ls
command to see the key.
Next, in the EC2 webpage that contain the running instances, select the “Instance ID” for “private instance 1”.
Click on “Connect”
In the “ssh client” tab
Whatever is the content in the “Example”, in the image above it is “ssh -i “machina.pem” [email protected]”, yours will be different, copy it and paste in the “public instance 1” console, then press enter. I believe in your instance if properly done you should see “mykey.pem”. You should be in your “private instance 1” console.
Install apache into your “private instance 1” with the following command:
sudo apt install apache2 -y
You will be to run this command and it goes through because the private instance has access to the internet, without this access the command will not work.
Repeat the same step for “public instance 2” and “private instance 2” to install apache into the private instance.
Our final task is to create an Application Load Balancer(ALB) which is the access point to reach our private instances. To get more information about an ALB, you can click here.
In the EC2 webpage, left sidebar, scroll down you will see “Load Balancing”
2. Click on “Target Groups”
Click on the “Create target group”
Select “Instances” as the target type.
In the “Target group name”, give it a name. Let’s call it “test-TG”
For the “VPC”, click on the dropdown and select the VPC we created.
For the “Protocol” and ”Port”, “HTTP” and 80 are sufficient respectively.
You can leave every other value as it is, then click “Next”
In the “Register targets” page select only the private instances.
Then click the “Include as pending below” button.
Click the “Create target group” button.
After the creation of the “Target Group”, our next focus is to attach this target group to a Load balancer.
In the EC2 webpage, left sidebar, scroll down you will see “Load Balancing”.
Click on “Load Balancer”
On the Load Balancer page, click on the “Create load balancer” button.
Click the "Create” button of “Application Load Balancer”.
Input a value for “Load balancer name”, let’s call it “test-LB”.
The “Scheme” and “IP address type” value should be left as it is.
For the VPC, select our created VPC.
For the Mappings selection, choose the two availability zones(AZ) in which our subnets are located. This is very important. To get this info, on the EC2 dashboard, click on instances, you will get the AZ your instances are on.
Select the security group we created above which is “test-SG”.
Every Load balancer needs a target group, in the Listeners and routing section, click on “Select target group”, out created target group “test-TG” will be displayed, select it.
Then click the “Created balancer” button.
The access point of our private servers is now the created application load balance(ALB).
In the EC2 webpage, left sidebar, scroll down you will see “Load Balancing”.
Click on “Load Balancer”
In the “Load balancers“ page, you will see the just created load balancer “test-TG”, the URL is the “DNS Name” value. Copy and paste it to your browser and you should be seeing the Apache default page.
With the above steps, you should be able to access private instances using an application load balancer.