Forem

Cover image for 🚀 Automating Flask To-Do App with AWS: Terraform, Jenkins & Docker
Pravesh Sudha
Pravesh Sudha

Posted on

🚀 Automating Flask To-Do App with AWS: Terraform, Jenkins & Docker

From Infrastructure as Code to CI/CD — How I Automated Deployment, Notifications & Cloud Setup

💡 Introduction

Welcome to the world of DevOps! 🚀 Today, we’re diving into Flask by building a simple To-Do List application and then taking it to the next level with DevOps automation. This is part of our Python-for-DevOps series, where we combine Python development with real-world DevOps practices.

I’ve created a basic To-Do app in Flask using ChatGPT, and now, we’ll supercharge it by integrating various DevOps tools:

AWS DynamoDB – To store our tasks efficiently in the cloud.

AWS SNS – To send an email notification whenever a task is marked as complete.

Docker – To containerize our application for easy deployment.

Terraform – To provision our AWS infrastructure as code.

Jenkins – To automate everything with a full CI/CD pipeline.

By the end of this tutorial, you’ll have hands-on experience with key DevOps tools, and your Flask app will be fully automated, running smoothly in the cloud. Make sure to follow along till the end!


💡Pre-Requisites

Before we dive into the project, let’s make sure we have everything we need. This tutorial assumes that you have:

An AWS account – We’ll be using AWS services like DynamoDB and SNS, so make sure you have access. If you don’t have an acount, you can sign up for a free tier on AWS.

Basic knowledge of Docker, Jenkins, and Terraform – You don’t need to be an expert, but a basic understanding of these tools will be helpful:

  • Docker → We’ll containerize our Flask app for easy deployment.

  • Jenkins → We’ll set up a CI/CD pipeline to automate deployment.

  • Terraform → We’ll use infrastructure as code to provision AWS resources.

If you’re new to any of these tools, don’t worry! I’ll guide you through the process step by step. Now that we have our prerequisites covered, let’s start by building our Flask To-Do app.


💡 Setting Up the Host Machine (EC2 Instance) 🚀

Before we start deploying our Flask To-Do app, we need a host machine where everything will run. For this, we’ll create an AWS EC2 instance and set it up with all the necessary tools:

Docker – To containerize our Flask application.

Jenkins – To automate deployment with CI/CD.

Terraform – To provision AWS infrastructure.

AWS CLI – To interact with AWS services.

1️⃣ Launch an EC2 Instance

Head over to the AWS Management Console and create an EC2 instance with the following specifications:

  • Amazon Machine Image (AMI): Ubuntu (Latest LTS)

  • Instance Type: t2.small

  • Storage: 15GB

  • Key Pair: Select an existing key or create a new one (download the .pem file).

  • Security Group: Open ports 5000 (for Flask) and 8080 (for Jenkins).

Image description

Once the instance is up and running, connect to it using SSH:

ssh -i <your-key.pem> ubuntu@<your-instance-ip>
Enter fullscreen mode Exit fullscreen mode

Now that we’re inside the EC2 instance, let’s install the required tools.

2️⃣ Install Docker

Docker will help us containerize our application so it runs smoothly across environments.

sudo apt update -y
sudo apt install -y docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker $USER && newgrp docker
docker --version  # Verify Docker installation
Enter fullscreen mode Exit fullscreen mode

3️⃣ Install Java (Required for Jenkins)

Jenkins requires Java to run, so let’s install it:

sudo apt install -y fontconfig openjdk-17-jre
java -version  # Verify Java installation
Enter fullscreen mode Exit fullscreen mode

4️⃣ Install Jenkins (For CI/CD Automation)

Add the Jenkins repository and install Jenkins:

sudo wget -O /usr/share/keyrings/jenkins-keyring.asc https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt update -y
sudo apt install -y jenkins
sudo systemctl enable --now jenkins
Enter fullscreen mode Exit fullscreen mode

Jenkins will now be running on port 8080.

5️⃣ Install Terraform (For Infrastructure as Code)

Terraform will help us automate AWS resource provisioning.

sudo apt update -y && sudo apt install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update -y
sudo apt install -y terraform
terraform --version  # Verify Terraform installation
Enter fullscreen mode Exit fullscreen mode

6️⃣ Install AWS CLI (For AWS Interactions)

We need AWS CLI to communicate with AWS services like DynamoDB and SNS.

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip -y
unzip awscliv2.zip
sudo ./aws/install
aws --version  # Verify AWS CLI installation

# Add Jenkins to the docker group
sudo usermod -aG docker jenkins
Enter fullscreen mode Exit fullscreen mode

Image description

7️⃣ Configure AWS Credentials

To allow Terraform and AWS CLI to access AWS services, configure your AWS credentials:

aws configure
Enter fullscreen mode Exit fullscreen mode

This command will prompt you to enter:

  1. AWS Access Key ID

  2. AWS Secret Access Key

  3. Default regionus-east-1

  4. Default output formatjson

👉 If you don’t have access keys, create them in AWS:

  • Go to AWS Console → IAMUsers

  • Select your user → Security Credentials

  • Click Create Access Key → Choose AWS CLI as the use case

  • Copy the Access Key ID and Secret Access Key

8️⃣ Open Required Ports in Security Group

Our application will run on port 5000 (Flask) and port 8080 (Jenkins). To ensure they are accessible, open these ports in the EC2 Security Group settings.

Image description

Now that our host machine is set up with all the necessary tools, we’re ready to deploy our Flask To-Do app.


💡 Cloning the Project & Setting Up AWS Resources

Now that our host machine (EC2 instance) is ready, it's time to set up the Flask To-Do app and configure AWS resources like DynamoDB and SNS.

1️⃣ Clone the Project from GitHub

We'll start by cloning the Flask To-Do app from my GitHub repository:

git clone https://github.com/Pravesh-Sudha/Python-projects.git
Enter fullscreen mode Exit fullscreen mode

This repository contains multiple projects, so navigate to the Flask To-Do app directory:

cd Python-projects/flask-todo-app
Enter fullscreen mode Exit fullscreen mode

📌 Optional: Feel free to fork the repository and make some custom changes for a personal touch!

2️⃣ Configure the App (Environment Variables)

The config.py file contains environment variables that you can modify:

SECRET_KEY = os.getenv("SECRET_KEY")
AWS_REGION = "us-east-1"
DYNAMODB_TABLE = "todo_tasks"
SNS_TOPIC_ARN = os.getenv("SNS_TOPIC_ARN")
EMAIL = "programmerpravesh@gmail.com" # Chang to Your Email
Enter fullscreen mode Exit fullscreen mode

👉 Update these variables in config.py, like setting your email for SNS notifications.

3️⃣ Create AWS DynamoDB Table & SNS Topic Using Terraform

Before testing the app, we need to create the DynamoDB table and SNS topic. Instead of manually creating them in AWS, we'll use Terraform to automate the setup.

Navigate to the Terraform setup directory inside the project:

cd terraform-setup
Enter fullscreen mode Exit fullscreen mode

Before running Terraform, open main.tf and update the SNS email endpoint (add your-email) to your own email.

Initialize Terraform

terraform init
Enter fullscreen mode Exit fullscreen mode

This command downloads and sets up Terraform dependencies.

Apply Terraform Configuration

terraform apply --auto-approve
Enter fullscreen mode Exit fullscreen mode

🚀 This will create:

✅ A DynamoDB table for storing to-do tasks.

✅ An SNS topic for sending email notifications when a task is completed.

4️⃣ Configure SNS Subscription

Once Terraform finishes, you'll see the SNS Topic ARN in the output. Copy it and save it as an environment variable:

export SNS_TOPIC_ARN=<the-output-from-terraform>
Enter fullscreen mode Exit fullscreen mode

Image description

Now, check your email inbox (the one you provided in main.tf). You should have received an email from AWS SNS. Click the confirmation link to activate your SNS subscription.

5️⃣ Install Python Dependencies & Run the Flask App

Now, navigate back to the Flask To-Do app directory:

cd ../flask-todo-app
Enter fullscreen mode Exit fullscreen mode

📌 Set up a virtual environment & install dependencies:

sudo apt install python3.12-venv -y  
python3 -m venv flask-env  
source flask-env/bin/activate  
pip3 install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

📌 Run the Flask app on EC2 (publicly accessible)

flask run --host='0.0.0.0'
Enter fullscreen mode Exit fullscreen mode

Image description

The application will now be running on:

http://<your-ec2-public-ip>:5000
Enter fullscreen mode Exit fullscreen mode

🎉 Congratulations! Your Flask To-Do App is live! 🎉

Image description

If you go to your mails, you will have the notification of the completed tasks, in my Case, “Vote for Trump“

Image description

Now that the app is running, we’ll containerize it using Docker. Before that, use the following command to destroy the resources you create using terraform:

terraform destroy
Enter fullscreen mode Exit fullscreen mode

💡 Automating the Workflow with Jenkins 🚀

Now that we have tested the Flask To-Do app manually, it's time to automate the entire process using Jenkins CI/CD. This will ensure that every time we push code changes, the application is built, tested, and deployed automatically.

1️⃣ Access Jenkins Dashboard

Jenkins runs on port 8080, so open your browser and go to:

http://<your-ec2-public-ip>:8080
Enter fullscreen mode Exit fullscreen mode

Jenkins will ask for an admin password. Retrieve it using:

sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Enter fullscreen mode Exit fullscreen mode

Image description

Copy the password, paste it into Jenkins, and continue.

Install suggested plugins

Skip "Create Admin User" (we’ll use the default admin)

Jenkins is now ready!

2️⃣ Assign IAM Role to EC2 for AWS Access

Since our application interacts with DynamoDB and SNS, our EC2 instance needs permissions to access these AWS services.

Create IAM Role for EC2:

  1. Go to AWS IAM ConsoleRoles

  2. Click Create Role

  3. Select AWS Service → EC2

  4. Attach these policies:

* `AmazonDynamoDBFullAccess`

* `AmazonSNSFullAccess`
Enter fullscreen mode Exit fullscreen mode
  1. Name the role:

    Flask-Todo-Dynamo-Role-For-EC2
    
  2. Click Create Role

Image description

Attach Role to EC2 Instance:

  1. Go to EC2 DashboardInstances

  2. Select your Flask EC2 instance

  3. Click ActionsSecurityModify IAM Role

  4. Select Flask-Todo-Dynamo-Role-For-EC2 and attach it

📌 Now, our EC2 instance can communicate with AWS services!

3️⃣ Configure AWS Credentials in Jenkins

Jenkins needs AWS credentials to deploy infrastructure using Terraform. Let’s add them:

1️⃣ Go to Jenkins DashboardManage JenkinsManage Credentials

2️⃣ Click SystemGlobal Credentials

3️⃣ Click Add Credentials

4️⃣ Select Secret Text

5️⃣ Add two credentials:

  • AWS_ACCESS_KEY_ID (Your AWS Access Key)

  • AWS_SECRET_ACCESS_KEY (Your AWS Secret Key)

    6️⃣ Click Save

Image description

Jenkins now has AWS access!

4️⃣ Install Jenkins Plugins for AWS & Terraform

We need Jenkins plugins for Terraform and AWS authentication:

  1. Go to Manage JenkinsManage Plugins

  2. Search for and install:

    Terraform Plugin

    AWS Credentials Plugin

  3. Restart Jenkins if required

Jenkins is now ready to deploy AWS resources!

5️⃣ Set Up Jenkins Pipeline

Now, let’s create a Jenkins Pipeline to automate our deployment:

1️⃣ Go to Jenkins Dashboard → Click New Item

2️⃣ Enter a name:

Flask-Todo-Dynamo
Enter fullscreen mode Exit fullscreen mode

3️⃣ Select Pipeline → Click OK

4️⃣ Scroll down to the Pipeline section

5️⃣ Set Pipeline from SCM

6️⃣ Select Git and enter the repository URL:

https://github.com/Pravesh-Sudha/python-projects
Enter fullscreen mode Exit fullscreen mode

7️⃣ Change the branch from master to main

8️⃣ Set the Script Path to:

flask-todo-app/Jenkinsfile
Enter fullscreen mode Exit fullscreen mode

9️⃣ Click Save

Jenkins is now set up to automate deployment!

6️⃣ Run the Pipeline 🚀

  1. Click Build Now

  2. Jenkins will:

* Clone the repository

* Deploy the Flask app using Terraform

* Build and run the Docker container

* Start the Flask To-Do app
Enter fullscreen mode Exit fullscreen mode
  1. Once the pipeline is successful, open:

    http://<your-ec2-public-ip>:5000
    

Image description

🎉 Your Flask To-Do App is live! 🎉

7️⃣ Final Step – Confirm SNS Subscription

Before testing email notifications, confirm the SNS subscription:

  1. Go to your email inbox (the one set in main.tf)

  2. Look for an email from AWS SNS

  3. Click the confirmation link

Image description

Now, SNS will send an email whenever a task is completed!

Image description

Image description

Image description


💡 Conclusion

Congratulations! 🎉 You’ve successfully built and automated a Flask To-Do App using AWS, Terraform, Docker, and Jenkins. Through this project, we explored the key concepts of DevOps and saw how different tools work together to create a fully automated CI/CD pipeline.

Key Takeaways:

Infrastructure as Code (IaC) – Used Terraform to automate AWS resource creation.

Containerization – Packaged the Flask app with Docker for easy deployment.

CI/CD Automation – Used Jenkins to automatically build, test, and deploy the app.

AWS Integration – Connected the app to DynamoDB for storage and SNS for email notifications.

This project provides a solid foundation for working with DevOps tools in real-world applications. You can extend it further by:

🚀 Adding unit tests before deployment.

🚀 Deploying the app on Kubernetes instead of a single EC2 instance.

🚀 Implementing AWS Lambda for serverless task management.

Final Thoughts 💡

DevOps is all about automation, scalability, and efficiency. With this project, you’ve taken a big step toward mastering these principles. Keep experimenting, improving, and applying these skills to bigger projects.

💬 Have questions or feedback? Drop them in the comments!

📢 Found this useful? Share it with your fellow DevOps learners!

Happy Coding & Automating! 🚀🔥

✨ For more informative blog, Follow me on Hashnode, X(Twitter) and LinkedIn.

Top comments (0)