In this article, we’ll deploy the Flask application we created in the previous article on AWS, using:
- Amazon RDS (Relational Database Service)
- Amazon ECR (Elastic Container Registry)
- Amazon ECS (Elastic Container Service)
And if all of this seems like too much effort, you can also use TinyStacks to set these services up and deploy a flask app to AWS. Getting started guide. Now back to the hard way.
Video Version:
Steps
- Create RDS instance of Postgres
- Test the RDS instance
- Clone and build the TinyStacks GitHub repository
- Create ECR repository
- Tag the Docker image and push it to the ECR repository
- Deploy to ECS using the ECR image
- Test with Postman (and TablePlus)
Create RDS Instance
Go to the AWS Management Consoleonsole and search for RDS:
Click on Create Database.
From the list of available options, select:
- Standard
- Postgres version 12.5
- Free Tier (If you’re a new customer or haven’t used RDS before, you can get up to 750 hours of usage free)
Choose a name for the instance (basically the name of the database), the master username (postgres), and the password (postgres). Confirm the password. (Make sure to use a more secure password in a production environment!)
You can leave the rest as it is, except for Connectivity:
We’ll set this up soon.
You can leave the rest as it is. Just double-check that the estimated monthly cost shows "Free Tier" (assuming you still have Free Tier credits). . Note that the cost of RDS instances may vary over time.
Then click Create Database:
While you wait, click on the database name and on the security group.
Click on the security group id, then on Edit Inbound rules. This will let us test our database with an external tool. If you want, you can skip this step. If you do, be sure that both the RDS instance and your app are in the same security group.
Now, add another inbound rule and make the RDS instance accessible:
Now we are ready to test the RDS instance.
Test the RDS instance
To test the RDS instance, we will use TablePlus, but you can use any tool you want. Alternative tools include:
Create a new PostgreSQL connection:
Fill in all the information required to connect:
- host: (the endpoint of the RDS instance)
- port: 5432
- username: postgres
- password: postgres
- database: postgres
You can disable SSL mode. (But make sure to leave SSL enabled when working in a production environment!)
Click Test Connection. If you see a connection is ok
message, you’re good to go. The database is empty for now.
Clone the repository, change branch, and build the Docker image
Clone the aws-docker-templates-flask repository from Tinystacks:
git clone https://github.com/tinystacks/aws-docker-templates-flask.git
Step into the directory
cd aws-docker-templates-flask
Now, switch your GitHub branch. You can check all the branches with the command git branch -a
.
git checkout flask-local-postgres
Then open this folder with your favorite IDE. IF you have Visual Studio code, you can type:
code .
Open a terminal and, in the folder where the docker-compose.yml
file is located, type:
docker compose build
ECR
Login into your AWS CLI, using your <AWS_ACCOUNT_ID>
and <REGION>
:
aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com
Create a new ECR repository using the prompt. Use your <REGION>
:
aws ecr create-repository --repository-name flask-app --region <REGION>
Then you can check the Amazon Console registries on ECR:
If you click on the repository name, you won’t see any images. That’s what we expect (for now).
Tag and push the Docker image on ECR
You can use the value <IMAGE_TAG>
to create an image with the tag latest
.
docker tag pythonapp <IMAGE_TAG>
Now push the image to the ECR repository:
docker push <IMAGE_TAG>
And check the image on the ECR repository:
ECS
Now, let's deploy our service using Amazon Elastic Container Service (ECS).
Search for ecs
on the AWS Management Console:
Click on Get Started:
Click on Custom and then click Configure:
This will let us configure the container task we want to run in our cluster.
Choose:
- Container name: any you want
- Image: the
<IMAGE_TAG>
(latest) - Port: 80
Next, in Advanced Configuration add an environment variable as defined in the docker-compose.yml
file:
For the values here, use:
- Key:
<DATABASE_URL>
- Value:
postgresql://postgres:postgres@<RDS_INSTANCE_IP>:5432/postgres
Remember to replace the database entry with the <RDS_INSTANCE_IP>
for your instance. You can find your <RDS_INSTANCE_IP>
on TablePlus or RDS.
Leave the rest as it is and click Update.
On Task definition, click Next:
Likewise, on Service, click Next:
On Cluster configuration, define a name for your cluster and click Next:
You’re all set! !Click Create:
Creation will take a couple of minutes. Once all the check marks have turned green, click View Service:
Click on the task and copy its Public IP. We will need that to test our application.
Test With Postman and Tableplus
First, let’s get all the items. If we get an empty list [], it means that the table has been created and we are getting no items. That’s what we expect, since we just created the table with no data.
GET Request at the endpoint: /items
To create a new item, make a POST request at the endpoint /items
:
Let's create 2 more items:
To get a single item, make a GET request, appending the id
of the item we want to retrieve at the end of the /items
path. For example /items/2
retrieves the item with id = 2.
(Don't mind the body in this request, that was from the last post request.)
To update an existing item, make a PUT request. Specify the id of the item we want to modify in the url and the new item in the body of the request:
If we try to GET the item 2 again, we’ll receive the updated item:
Finally, to delete an existing item - for example, the item with id = 3 - we can make a DELETE quest at the path /items/3
:
If we try to get all the items again, we only get two:
A final test using TablePlus:
GitHub Repository (branch: flask-local-postgres): https://github.com/tinystacks/aws-docker-templates-flask.git
Now that you know what it takes to stand up AWS services and deploy a flask app, skip all of that and have TinyStacks TinyStacks do most of the work for you.