Deploying Flask API in AWS

Pedro Rodriguez G.
6 min readApr 29, 2020

Step-by-step guide to deploy your first AWS REST API.

Introduction

Typically, once a data scientist finishes developing a model, he/she ends up generating a pickle file of some kind and needs to deploy it somewhere. It is very common needing to deploy the model using an Apache server, as a service being served through a REST API.

In this post, i will explain the basic steps to deploy your model in an easy way.

(1) Instance configuration (AWS)

Create an account in AWS and initialize an EC2 instance: login and go to Services -> EC2 -> Running Instances -> Launch Instance. When creating a new instance, you will be asked if you want to create a new key or if you already have one. This is very important for accessing it seccurely later. In this case, we create a Linux Instance, and use ubuntu to build the application.

Keep your .pem file securely. You will need it every time you access the instance through an SSH tunnel. Keep in mind that each instance will be created in a specific location. You will need to remember which location you used for this instance. In this case, we created it in Ohio (see top-right corner of the image).

To access your instance: right-click on the instance, click ‘Connect’ and copy the “ssh …” that will appear into a terminal (the terminal must be opened in the same directory where your saved your .pem key file). This should get you into your newly created instance. For example: ssh -i “aws_ec2_C5d.pem” ubuntu@ec2–*-*-*-*.us-east-2.compute.amazonaws.com, where “{filename}.pem” is your key file.

Now, you need to do two things, necessary to make the instance accessible through HTTPS requests, that is the typical way of communicating through API REST requests.

  1. Allow inbound connections to the port 443: to do this got to ‘Network&Security’ -> ‘Security Groups’ (bottom-left corner of the image) and modify to allow inbound connections into port 443. Sometimes you might also need to allow inbound SSH connections through port 22, but generally this comes by default.
  2. Create a hosted zone, so as to have a web URL certified by a CA, which will later allow you to respond to requests by using secure connections (HTTPS). To do this, go to ‘Services’ -> ‘Route 53’ -> ‘Create Hosted Zone’. Once you have created the hosted zone, you will need to map inbound connections from that URL with your instance. In the following picture, the instance ec2–*-*-*-*.us-east-2.compute.amazonaws.com is mapped to a specific IP address.

OK. Now, you are all set to get into your new instance, upload your Machine Learning models into it implement your REST API, which listens on port 443 of your instance and serves online requests.

(2) Uploading code & data into your instance

There are lot’s of ways of doing this, but here i will recommend one of the easiest: download Filezilla, click on the servers icon located on the top-left corner of the screen and configure the following, as seen in the image: Protocol=SFTP, Host=’your ec2 instance’, Port=22, Logon Type=’Key file’, User=’ubuntu’ (by default, the instance’s user name is ubuntu, and has no password), Key file=’directory where you saved the .pem key file’. Click connect and you will have direct access to your instance. You can download anything you want into the instance.

(3) Application configuration

This is the most tricky part. We are going to implement a Python Web Server with Flask. While learning to to this, i followed the instructions given in [1], but i write here the important parts. However, i will assume that you have correctly installed most of the required programs and libraries, and that you are using python3. Also, that your project is called ‘project’ and that the root of the application is located in /home/ubuntu/project/src/server/app.py.

First, create a virtual environment with: python3 -m pip install virtualenv. Next, cd project -> virtualenv venv (to create a new directory with a virtual environment, a context in which the apache server will execute). Next, run the following: ‘. venv/bin/activate’, and once in this context, install all the libraries you will need. To install Flask: python3 -m pip install Flask.

Now, create the root file: app.py (something like the next image will do it).

OK. Now, you have your app. You can try executing it locally by executing .sh file like the following run.sh:

Now that you know your app is running ok locally, you can disconnect from the virtual environment. Now, we will do the final configuration needed to make this service available from anywhere.

4) Apache web server configuration

First, you will need to install mod-wsgi: run sudo apt-get install apache2 libapache2-mod-wsgi-py3 on the terminal. Once successfully installed, go to /home/project/src/server/ directory and create a new file called app.wsgi like the following:

Next, create a symbolic link so that the project’s directory appears in /var/www/html/project: sudo ln -sT ~/project /var/www/html/project and enable wsgi with sudo a2enmod wsgi.

OK. We are almost there, just two more steps:

  1. Generate the credentials necessary for the Certificate Authority (CA), for the HTTPS connections. There are a couple of ways to do this. Here, you will user certbot. You can go to [2] and follow the instructions. Basically, you will need to be able to generate two files, corresponding to your hosted zone. In the last step, you will need to run the following code: sudo certbot — apache. In the end, you will end up with two files, which we will call server.crt and server.key. You will copy server.crt file into /etc/ssl/certs/server.crt and the server.key into /etc/ssl/private/server.key.
  2. Modify the apache server configuration by running: sudo vim /etc/apache2/sites-enabled/000-default.conf, and modifying the file to have something like the following image.

OK. Now, you should be all set. Cross your fingers and run sudo apachectl restart. The error log can be found with vim /var/log/apache2/error.log.

Conclusions

If you were able to follow all the steps described here, your API REST should be serving requests in the domain you created. Making modifications to the code introduced here is straightforward, and it should be easy to extend it so as to serve things more interesting than a simple “Hello World!” string!

Bibliography

[1] https://vishnut.me/blog/ec2-flask-apache-setup.html

[2] https://certbot.eff.org/lets-encrypt/ubuntuxenial-apache

[3] https://www.checkars.com

--

--

Pedro Rodriguez G.

MS Computer Science & MS Financial Engineering. I am interested in data science and it's applications to the fields of finance and economics