This repository contains code for building and deploying a Flask-based backend web application to AWS using Terraform and Packer.
It includes several AWS services such as EC2, Load Balancer, Autoscaler, VPC, RDS, S3, Cloudwatch, Route 53, and IAM.
A CI/CD pipeline is implemented using GitHub Actions for building, testing, and deploying the application.
- Tech Stack
- Prerequisites
- Cloning
- Usage
- CLoud Deployment
- RESTful API interaction
- Load Testing
- CI/CD
- Contributing
- Flask - Backend webapp
- Terraform - Infrastructure as Code
- Packer - Amazon Machine Images
- AWS cli, Zsh - AWS deployment
- Postman - RESTful API's testing
- Jmeter - Load testing
- unittest - webapp unit testing testing
- GitHub Actions - CI/CD
- GIT - Version control
- statsd - Metrics logging
- boto3 - S3 connection
- bcrypt - user authentication
- sqlalchemy - Bootstrapping database
- VS Code - webapp development
- PostgreSQL - initial database. Later migrated to RDS
- pip
- Python 3.8 or higher
- AWS account with IAM user credentials
- Zsh , AWS Cli
- Terraform
- Packer
- Git
- JMeter
To clone the project repository, run the following command in your terminal:
- git clone [email protected]:Sukruthmothakapally/Flask-AWS-Terraform-Packer-CICD.git
To use the application locally, navigate to the webapp directory and run the following command:
- pip install -r requirements
- python app.py
- note : Might need to setup database connection accordingly
- Step 1 - Get a SSL certificate from Namecheap or any other provider. Import SSL certificate to AWS using the below command -
- aws acm import-certificate --profile xxxx --region xxxx --certificate file://xxxx.crt --private-key file://private.key --certificate-chain file://xxxxx-bundle
- Step 2 : Use Packer to build Amazon Machine Image consisting of webapp artifacts. Navigate to webapp directory and run the below command -
- packer build -var 'access_key_id=xxxx' -var 'secret_access_key=xxx' packer_amibuild.json
- Step 3 : Create a values.tfvars file with custom values for the infrastructure in aws-infra directory
- Step 4 : Use Terraform to create AWS Infrastructure for the deployment. Navigate to aws-infra directory and run the below command -
- terraform init
- terraform fmt
- terraform plan -var-file=values.tfvars
- terraform apply -var-file=values.tfvars
- Use Postman or any other REST cient to interact with the endpoints
- Check if deployment is sucessful and the webapp is running. Select GET in Postman and enter the URL - https:///healthz
- /healthz is the endpoint for testing if the webapp is running successfully. If it returns '0K' - connection is successful.
-
Public - Operations available to all users without authentication
- GET /healthz - Health endpoint
- POST /v1/user - Create a new user account
- GET /v1/product/{productId} - Get Product Information
-
Authenticated - Operations available only to authenticated users
- GET /v1/user/{userId} - Get User Account Information
- PUT /v1/user/{userId} - Update User's account information
- POST /v1/product - Add a new product
- PUT /v1/product/{productId} - Update Product
- PATCH /v1/product/{productId} - Update Product
- DELETE /v1/product/{productId} - Delete Product
- GET /v1/product/{product_id}/image - Get List of All Images Uploaded
- POST /v1/product/{product_id}/image - Upload an image to S3
- GET /v1/product/{product_id}/image/{image_id} - Get image Details
- DELETE /v1/product/{product_id}/image/{image_id} - Delete the image from S3
Use Jmeter to perform load testing on the webapp. Autoscaler will increment or decrement the number of EC2 instances based on load and cloudwatch alarms.
For continuous Integration and Continuous Deployment, setup Github Actions with -
- terraform_packer.yml - Creates AMI using Packer and then creates the infrastructure using Terraform. Can change to "on: PUSH"
- pull_request_raised.yml - Performs unit testing whenever new pull request is raised
- pull_request_merged.yml - Runs only on successful completion of above workflow. Updates the AMI with the changes and perform instance refresh
Contributions are welcome! To contribute to the project, fork the repository and create a pull request with your changes.