πŸš€ Automating Flask To-Do App with AWS: Terraform, Jenkins & Docker

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    πŸš€ 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).





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






    ssh -i ubuntu@







    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...ns.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:

    1. AWS Access Key ID
    2. AWS Secret Access Key
    3. Default region β†’ us-east-1
    4. 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=










    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://: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://: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:

    1. Go to AWS IAM Console β†’ Roles
    2. Click Create Role
    3. Select AWS Service β†’ EC2
    4. Attach these policies:



    * `AmazonDynamoDBFullAccess`

    * `AmazonSNSFullAccess`



    1. Name the role:





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





    Attach Role to EC2 Instance:

    1. Go to EC2 Dashboard β†’ Instances
    2. Select your Flask EC2 instance
    3. Click Actions β†’ Security β†’ Modify 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 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:

    1. Go to Manage Jenkins β†’ Manage 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







    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:






    Contribute to Pravesh-Sudha/Python-projects development by creating an account on GitHub.








    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 πŸš€

    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




    1. Once the pipeline is successful, open:




      http://:5000





    πŸŽ‰ 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





    βœ… 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.




    More...
Working...