avatarMichael Whittle

Summary

The article provides a step-by-step guide on deploying a Python Flask API on an Apache web server using an Amazon EC2 instance.

Abstract

The article, "Build a Web Server with Flask and AWS," is a comprehensive tutorial on setting up a scripted Apache web server with a Python Flask API on Amazon Web Services (AWS). It walks readers through the process of launching an EC2 instance, selecting the appropriate Amazon Machine Image (AMI), configuring instance details, adding storage, and setting up security groups to allow HTTP traffic. The author emphasizes the use of the AWS free tier for those engaging in hobby projects or research and development. A key feature of the setup is the use of "User data" to execute a script that automates the installation and configuration of the necessary software, including Flask and Apache. The guide also touches on the importance of assigning a public IP address, creating a swap file, and using a Python virtual environment. The article concludes with the successful deployment of the web server, demonstrated by a "Hello world!" message served by both the Flask application and the Apache server.

Opinions

  • The author believes that the "User data" functionality in AWS EC2 is underrated and highly beneficial for automating server setup.
  • The guide assumes that readers may be new to AWS or server setup, as it explains basic concepts and the significance of the free tier.
  • The author suggests that using a t2.medium instance type would be a realistic minimum for a production environment, indicating a preference for performance and reliability over cost for serious applications.
  • By including the option to open TCP port 5000, the author acknowledges the usefulness of testing the Flask server independently from Apache, which can be beneficial for troubleshooting and development.
  • The article implies that the setup process, although automated, requires patience as it may take up to 10 minutes for the instance to be fully provisioned and ready.
  • The author encourages readers to engage with the content by following them on Medium and LinkedIn, suggesting a desire to build a community or readership around their technical content.
  • There is an implicit endorsement of using SSL/TLS for a secure web server, although it is noted to be out of scope for the current article.

Build a Web Server with Flask and AWS

How to Build a Scripted Apache server with a Python flask API in AWS

Photo by Austin Chan on Unsplash

I’m going to walk you through deploying a scripted Apache web server with a Python flask API in minutes. This will be done with an Amazon EC2 instance.

The first step is to log into the Amazon AWS console. Search for “EC2” in the search or click on “EC2” in the “Recently visited services” if it is there.

Image by Author

The EC2 console should look something like this. Click on “Launch instances” to launch a new instance.

Image by Author

I’m going to assume you want to use the free tier. Most of the AWS services provide a free tier which is great for hobby projects or research and development.

Please select “Red Hat Enterprise Linux 8 (MVM), SSD Volume Type” in the list below. You will see it says “Free tier eligible” below it.

Image by Author

For this demonstration please select “t2.micro”, which is also “Free tier eligible”. If you are planning on using this in production and happy to pay for this then you can select a more appropriate option below. I would normally say “t2.medium” would be the realistic minimum if you were paying for this.

Image by Author

This is arguably the most important screen in this walkthrough. Make sure you set “Auto-assign Public IP” to “Enable”. You can also keep this disabled and deploy a load balancer or use an Elastic IP as an alternative but this is out of scope. For the purpose of this walkthrough we are going to auto assign a public IP. Please be aware that this public IP will change every time the instance is started, it’s not permanent!

Image by Author

The most important part here is the “User data” under “Advanced Details”. This is such underrated functionality but it really is amazing. This allows you to provide a script to be run after the instance is provisioned. I’ve created a public Gist with the script you need to include in the “User data” section.

This will do the following:

  • Update the system using the yum package manager
  • Install the necessary packages using yum
  • Upgrade the Python package manager (PIP)
  • Install Flask using PIP
  • Set Apache to start on system boot
  • Create a swap file
  • Pull down the Flask files I created for you
  • Create a Python virtual environment
  • Restart Apache

The next part is to select the storage. Just accept the default size.

Image by Author

You can accept the default settings for the tags. I normally like to add at least “Name” and “Project” tags as they are good for general administration and billing but for the purposed of this walkthrough it’s not necessary.

Image by Author

This next part is important as well, so pay attention. We will be giving our instance a public IP address but this does not mean it’s visible to the outside world. In fact, by default, it won’t be. Create yourself a new security group, and give it a name. Something like “acl-web-in” may be an appropriate name. You need to allow TCP 80 (HTTP) for a basic unencrypted web server. SSL/TLS is out of scope of this article. For the purposes of this walkthrough you can just open up TCP 80 to the outside world. You may wonder what that custom TCP 5000 is there for. This is optional, and allows you to test flask on its own without Apache. I’m including it here for your information. You can either leave it in until everything is working or omit it now, it’s up to you.

Image by Author

The next page is the final review before launch. We should be good to go, so just click “Launch”.

When you click “Launch” it will ask you if you want to create a new key pair or use an existing key pair. I have a key already, so I will use mine. If you don’t have a key already, create one, and download it. It will be a .pem file.

Image by Author

When we click “Launch Instance” it will initiate the build. This will include the script from “User data”. This is a completely automated process to please allow for 10 (give or take) minutes to complete fully.

Select “Instances” from the side menu and click on the instance being provisioned. As you can see below my “Instance state” is “Pending”. What we want to extract here is the “Public IPv4 address”. Please make a note of yours, for this build mine is 18.203.85.109.

Image by Author

That that’s it folks!

In roughly 10 minutes, a completely automated build of an Apache web server running Python flask will compete. You will be able to browse to your web server using the IP address extracted above.

Image by Author

What is serving that “Hello world!” as that’s not basic HTML.

I can demonstrate this by logging into my EC2 instance.

.ssh % ssh -i AWSPersonal.pem ec2-user@18.203.85.109
The authenticity of host '18.203.85.109 (18.203.85.109)' can't be established.
ECDSA key fingerprint is SHA256:oew0XcqG8QRYr2aK+qOmbXqBhQ56apX+xcrswCHZnUc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

I sudo to root.

[ec2-user@ip-172-31-28-79 ~]# sudo su -
[root@ip-172-31-28-79 ~]#

I browse to the web root.

[root@ip-172-31-28-79 ~]# cd /var/www/html
[root@ip-172-31-28-79 html]#

I enter the Python virtual environment.

[root@ip-172-31-28-79 html]# source bin/activate
(html) [root@ip-172-31-28-79 html]#

And fire up the local flask server.

(html) [root@ip-172-31-28-79 html]# export FLASK_APP=run.py
(html) [root@ip-172-31-28-79 html]# flask run --host=0.0.0.0
 * Serving Flask app 'run.py' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://172.31.28.79:5000/ (Press CTRL+C to quit)
<removed> - - [20/Aug/2021 08:44:15] "GET / HTTP/1.1" 200 -
<removed> - - [20/Aug/2021 08:44:15] "GET /favicon.ico HTTP/1.1" 404 -

If I open, “http://18.203.85.109:5000” in my browser I still see the “Hello world!” message but it’s being served by the flask server and not Apache. This is an optional step but useful for testing and troubleshooting purposes.

For interest sake the “Hello world!” is being served with a REST GET call using the Apache “mod_wsgi.so” module in Apache. The file being loaded is, “app/__init__.py”.

If you found this useful please don’t forget to let me know in the comments, and follow me on Medium.

More content at plainenglish.io

Aws Ec2
Coffee2021
Web Development
Programming
Python
Recommended from ReadMedium