AWS CDK with Python — ALB + Fargate + Flask

Mohammed Shahbaaz Shareef
AWS in Plain English
7 min readAug 28, 2021

--

In this post, I want to introduce AWS CDK and its advantages. For this demonstration, I also coded a simple Flask webserver that exposes two endpoints, one for a health check and one for reversing a string.

As a DevOps practitioner, I am constantly thinking of automating a lot of stuff, Infrastructure as code is no different. we all have been in situations where we must have come across lengthy cloud formation templates of our infrastructure at some points.

What if there is a different way to set up infrastructure and automate?

Yes, of course, AWS has got you covered. AWS CDK provides a framework of constructs in some languages like Python, TypeScript, etc, using which we can set up and automate infrastructure in AWS.

AWS CDK behind the scenes generates Cloudformation templates based on the code we have written, the advantage of code here is we can use all syntax constructs of our programming language rather than using templates that are declarative (JSON, YAML).

While developing this simple Python application, or, for that matter, any project, the biggest advantage you have is infrastructure code is maintained along with your application code.

While creating infrastructure, it is of utmost crucial importance to follow and maintain best practices.

What if this comes inbuilt?

When we use CDK, in fact, it does. In CDK, they are known as patterns. These patterns help us achieve a particular Infra setup task. Apart from patterns, AWS CDK also comes with and level 1 and level 2 constructs.
Also, the AWS CDK CLI deserves a mention and the nice documentation embedded in the sample app deserves a mention.

I will now demonstrate the creation of a sample app that maintains application code as well as infrastructure through code

Prerequisites:

  • AWS CLI
  • AWS CDK
  • Python

Step 1. Create a sample CDK app

Let’s create a project directory and a Python environment for this project.

Working with Python packages can sometimes become difficult. Luckily, the AWS CDK sample app with Python comes with a one-click venv setup.

mkdir aws-cdk-python-flask
cd aws-cdk-python-flask // Initializing a cdk sample pyhton project
cdk init --language python
.venv\Scripts\activate

Output:

The file will have its original line endings in your working directory
Please run 'python -m venv .venv'!
Executing Creating virtualenv...
✅ All done!
****************************************************
*** Newer version of CDK is available [1.120.0] ***
*** Upgrade recommended (npm install -g aws-cdk) ***
****************************************************
PS E:\aws-cdk-python-flask>

Once these commands execute correctly, we should have a setup that looks like this:

Step 2. Infrastructure with Python Constructs

So let’s have a look at our application architecture. We will be hosting our back-end on a Flask container that will run on Fargate. Fargate is a managed serverless container engine, which will run our container based on a docker image and also register our application container as a target group to ALB. There is no front-end as such because we are just exposing this API directly. We can make requests to this back-end and get a response.

Let’s edit our file aws_cdk_python_flask\aws_cdk_python_flask_stack.py to import the necessary packages:

from aws_cdk import core as cdkfrom aws_cdk import (core, aws_ec2 as ec2, aws_ecs as ecs,aws_ecs_patterns as ecs_patterns)

Add the following code to __init__ function:

In just these 12 lines, we can set up a VPC, create an application load balancer, Create an ECS Fargate type service and task definition.

Instead of pushing my docker image to ECR/Docker hub, here I am utilizing ContainerImage.from_asset to point it to my application code directory where I have the docker file.

I have set the task definition and container properties to remain free tier for this project.

Step 3. Create Flask app

We will now create an application directory in the project root and maintain application code here:

mkdir server

Set up the files as follows:

I will create two routes in Flask, one for Alb and one for reversing a string.

I am running this server on port 80. So traffic is served from port 80 on container. I choose port 80 so it works with default settings, we can modify this from container task definition to run on a different port and make the same changes in the target group.

Test our app locally:

Step 4. Dockerize Flask app

To run in Fargate, our application need to be dockerized, so for dockerizing this application I am simply using Python slim as the base image and requirements.txt takes care of the dependencies to run the Flask code.

In this step, we will package and our application along with dependencies, here flask, so that we can easily build and run our application anywhere. It can run as a container in your dev, on ECS EC2 type or Fargate.

vi Dockerfile

Let’s create a docker file:

FROM python:3.8-slim-busterEXPOSE 80WORKDIR /appCOPY ./requirements.txt /app/requirements.txtCOPY server.py /appRUN python -m pip install -r requirements.txtCMD ["python", "server.py"]

Here, I am using the base image as python3.8, which is lightweight and serves our purpose. I am setting up a work directory inside container and copying requirements.txt (Flask==1.0.2 >> requirements.txt) and then the last statement starts our server.py. I have set up debug=True in Flask so that we can see our container logs/ AKA flask logs in cloud watch.

Step 5. Make necessary changes to the configuration before deploying

env=core.Environment(account=’your account id ', region=’your error)

Before we use CDK commnds to deploy, we need to set which account and region we want to deploy. When we use a cdk init, the structure is set up for us — in the root directory, we have app.py, where we can define the account and region.

Step 6. Deploy :-)

We are done with the application code as well as the infrastructure code.

Now it is time to sit back and relax while AWS CDK does its magic.

We use the following commands:

cdk synth # Synthesizes and prints the CloudFormation template for this stack
cdk bootstrap # Deploys the CDK toolkit stack into an AWS environment\
cdk deploy # deploys the stack to awscdk destroy # destroys the stacks/ resources created

Once you do a cdk bootstrap, you should see a cloud formation template setup like this:

We can do a cdk deploy. It will deploy the Cloudformation stack. So the AWS CDK is looking at your access key and secret key from what you have configured at the AWS CLI configure level. Make sure that it is set up beforehand.

It’s going to create an application load balancer and then it is going to create a Fargate container and then modify the application load balancer to register our container.

Our ALB and Fargate must be created at this point and our container should be in a steady state to serve traffic. The whole process took less than 5 minutes to get up and running after CDK deploy. :-)

Application Serving Traffic From ALB

To check and debug any issues, we can use CloudWatch to fetch logs from the container and see what's going on.

To safely destroy everything we created, we can use CDK destroy to delete all associated resources with our stack.

Conclusion

In this post, I have utilized AWS CDK to deploy our infrastructure. I have made use of its constructs and powerful features to create, configure and spin up infrastructure to support our project in minutes.

--

--