Deploying a Flask App to AWS – Overview

This project will get the Flask fiance and savings calculator up and running on AWS from scratch.

There are a few prerequisites required before hand, such as AWS CLI access to your account. The containers repo used is also private and therefore there is an access token that needs to be created in the repo.

I could have made this a public repo, but I wanted to test with a private repo how the EC2 instance can clone the repo.
There are many parts to this project. I’ll start at the bottom and work my way to the application layer.

AWS Infrastructure

There are two CloudFormation templates. The first will create a VPC base. This is lifted from previous projects and is there for Security Groups a new VPC, Internet access and a VPC Endpoint that isn’t used as the EC2 instance created is in a public subnet.

The first CloudFormation template requires an IP address that is used to only allow access from that source. The IP is automatically found and added to the template parameters.

The second CloudFormation template is there to create the EC2 instance that will host the Flask app in Docker. The CloudFormation template and deploy_docker.sh script will install Git, Docker and docker-compose. It will then clone the containers repo and build the containers with docker-compose.

GitLab

GitLab is currently only used for storing the project code. There is no CI/CD pipeline as of yet. The repo is private, which means that there needs to be an access token to allow the EC2 instance to clone the project.

EC2 & Docker

Docker and docker-compose are both installed by the CloudFormation template. The deploy_docker.sh script will create secrets in the AWS Secrets Manager for the EC2 instance to access securely.
The EC2 instance can then use these tokens to clone the repo, build the containers with docker-compose and setup the communication between Flask and the Postgres DB.

Flask App & Postgres DB

Once the containers have been built and are running access will be granted from the source IP address that was provided in the script. This keeps everything private for testing purposes.

Deployment

The deployment of the Flask app is all taken care of by a bash script. The entire deployment has been created from several small problems. I’ll detail some of the more interesting ones below.

Getting AWS Private Key from CloudFormation

When creating a key pair in the AWS console you are prompted to download the .pem private key. However, when creating the key pair using CloudFormation this cannot be done, and the private key cannot be downloaded from the console after creation.

The below are the AWS CLI commands to get the .pem file

Creating a GitLab Deploy Token

As the repo is private, I have used a deploy token instead of an SSH key to access the project repo only. To create a deploy token navigate to the project repo, settings and Repository. The Deploy token can be created there. The scope of this key is to just access this repo as read only.

Once the token has been created, there will be a user and a token that will need to be added to the EC2 instance that is running the Flask container. The deploy.sh script has the AWS CLI commands to get the token into the AWS Secrets Manager.

I have included a .env file in the repo that contains all of the secrets in. This file is not included in the repo, but is stored locally and the deploy.sh script uses this to create the secrets.

Creating Secrets in AWS Secrets Manager

In the deploy.sh script, there is a section that will load in the .env and then with a function to check if there is already a secret present in the Secrets Manager. If the secret is not present, then the secret will be created.

Leave a Comment

Your email address will not be published. Required fields are marked *