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).
Once the instance is up and running, connect to it using SSH:
ssh -i <your-key.pem> ubuntu@<your-instance-ip>
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
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
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
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
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
7️⃣ Configure AWS Credentials
To allow Terraform and AWS CLI to access AWS services, configure your AWS credentials:
aws configure
This command will prompt you to enter:
AWS Access Key ID
AWS Secret Access Key
Default region →
us-east-1
Default output format →
json
👉 If you don’t have access keys, create them in AWS:
Go to AWS Console → IAM → Users
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.
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
This repository contains multiple projects, so navigate to the Flask To-Do app directory:
cd Python-projects/flask-todo-app
📌 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
👉 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
Before running Terraform, open main.tf
and update the SNS email endpoint (add your-email) to your own email.
Initialize Terraform
terraform init
This command downloads and sets up Terraform dependencies.
Apply Terraform Configuration
terraform apply --auto-approve
🚀 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>
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
📌 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
📌 Run the Flask app on EC2 (publicly accessible)
flask run --host='0.0.0.0'
The application will now be running on:
http://<your-ec2-public-ip>:5000
🎉 Congratulations! Your Flask To-Do App is live! 🎉
If you go to your mails, you will have the notification of the completed tasks, in my Case, “Vote for Trump“
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
💡 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
Jenkins will ask for an admin password. Retrieve it using:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
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:
Go to AWS IAM Console → Roles
Click Create Role
Select AWS Service → EC2
Attach these policies:
* `AmazonDynamoDBFullAccess`
* `AmazonSNSFullAccess`
-
Name the role:
Flask-Todo-Dynamo-Role-For-EC2
Click Create Role
Attach Role to EC2 Instance:
Go to EC2 Dashboard → Instances
Select your Flask EC2 instance
Click Actions → Security → Modify IAM Role
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 Dashboard → Manage Jenkins → Manage Credentials
2️⃣ Click System → Global 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
✅ Jenkins now has AWS access!
4️⃣ Install Jenkins Plugins for AWS & Terraform
We need Jenkins plugins for Terraform and AWS authentication:
Go to Manage Jenkins → Manage Plugins
Search for and install:
✅ Terraform Plugin
✅ AWS Credentials PluginRestart 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
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
7️⃣ Change the branch from master
to main
8️⃣ Set the Script Path to:
flask-todo-app/Jenkinsfile
9️⃣ Click Save
✅ Jenkins is now set up to automate deployment!
6️⃣ Run the Pipeline 🚀
Click Build Now
Jenkins will:
* Clone the repository
* Deploy the Flask app using Terraform
* Build and run the Docker container
* Start the Flask To-Do app
-
Once the pipeline is successful, open:
http://<your-ec2-public-ip>:5000
🎉 Your Flask To-Do App is live! 🎉
7️⃣ Final Step – Confirm SNS Subscription
Before testing email notifications, confirm the SNS subscription:
Go to your email inbox (the one set in
main.tf
)Look for an email from AWS SNS
Click the confirmation link
✅ Now, SNS will send an email whenever a task is completed!
💡 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)