Deploy Django Application on AWS ECS Fargate using GitHub Actions and Terraform, A Complete CI/CD PipeLine

Muhammad Rashid
6 min readMay 6, 2024

--

Learn how to deploy a Dockerized Django application on AWS ECS Fargate effortlessly with GitHub Actions and Terraform in this comprehensive tutorial.

Table of contents:

  1. Create an Ec2 Ubuntu instance
  2. Install Packages on Ec2 Instance (Docker, AWS CLI)
  3. Configure AWS CLI on EC2, Also on the Local Machine
  4. Setup Self Hosted runner on Ec2
  5. Create db secret(Password) on AWS Secret Manager, with name ‘/dev/djangoapi/db/password’
  6. create ECR Repository on AWS
  7. Create CI/CD Pipeline using Github Actions
  8. GitHub Actions (Build)
  9. Create infra using Terraform
  10. GitHub Actions (Build and Deploy)
  11. Add SSL and domain.

Note: This Article is made for the video to utilize the commands used in the video. So make sure you watch the video to get this done.

1. Create an Ec2 Ubuntu instance

The first step in deploying a Django application on AWS is to create an EC2 instance. An EC2 instance is a virtual server that runs in the AWS cloud. To create an EC2 instance, you will need to log in to your AWS account and go to the EC2 dashboard.

Once you are in the EC2 dashboard, click on the “Launch Instance” button. From there, you will be prompted to select an Amazon Machine Image (AMI). An AMI is a pre-configured virtual machine image that includes the operating system, application server, and other software needed to run your application.

For this tutorial, we will use the Amazon Ubuntu Machine. After selecting the AMI, select the instance type that best suits your needs. For small to medium-sized applications, a t2.medium instance is a good choice.

Make sure you create in the same region where you will create infrastructure.

2. Install Packages on Ec2 Instance (Docker, Terraform, AWS CLI)

Install Docker

sudo apt-get update 
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu
newgrp docker
sudo chmod 777 /var/run/docker.sock

Install AWS CLI

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

3. Configure AWS CLI on EC2

Before You configure AWS, Get access and secret keys.

also save the CSV file for later use.

I have explained this in the video.

aws configure

4. Setup Self Hosted runner on Ec2

Now Go to GitHub Repository and click on Settings -> Actions -> Runners

Click on New self-hosted runner

Now select Linux and Architecture X64

Use the below commands to add a self-hosted runner

Note: In pic, Commands are related to my account, Use your commands, they will appear on your GitHub self-hosted runner Page.

Now SSH to your AWS instance to connect with your Instance.

And Past/Run these commands.

mkdir actions-runner && cd actions-runner

Command “mkdir actions-runner && cd actions-runner” serves to generate a fresh directory named “actions-runner” within the present working directory. Subsequently, it swiftly switches the current working directory to this newly created “actions-runner” directory. This approach streamlines file organization and facilitates executing successive actions within the newly formed directory without the need for separate navigation.

Download the latest runner package

curl -o actions-runner-linux-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz

Validate the hash.

echo "29fc8cf2dab4c195bb147384e7e2c94cfd4d4022c793b346a6175435265aa278  actions-runner-linux-x64-2.311.0.tar.gz" | shasum -a 256 -c

Now Extract the installer

tar xzf ./actions-runner-linux-x64-2.311.0.tar.gz

Create the runner and start the configuration experience

./config.sh --url https://github.com/codewithmuh/react-aws-eks-github-actions --token AMFXNTP3IVE6IAZSWO3ZEGDFT2QV6

If you have provided multiple labels use commas for each label.

Do not commands except ./run.sh.

Create systemd Service File on EC2.

sudo nano /etc/systemd/system/run-script.service

Paste the below content

[Unit]
Description=Script Runner Service
After=network.target
[Service]
Type=simple
Restart=always
User=ubuntu
WorkingDirectory=/home/ubuntu/actions-runner
ExecStart=/home/ubuntu/actions-runner/run.sh
[Install]
WantedBy=multi-user.target

Run These Scripts.

sudo systemctl daemon-reload 
sudo systemctl enable run-script
sudo systemctl start run-script
sudo systemctl status run-script

5. Create db secret(Password) on AWS Secret Manager, with name ‘/dev/djangoapi/db/password’

First, you have to configure aws cli locally and run a command.

aws ssm put-parameter --name "/dev/djangoapi/db/password" --value "admin123" --type String --tags '[{"Key":"Region","Value":"ap-south-1"},{"Key":"Environment", "Value":"Dev"},{"Key":"Service", "Value":"admin123"}]'

6. Create an ECR Repository on AWS

We have to create an ecr repo with the name django-app, watch video to learn about creation.

Before you create GitHub actions.

Add AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in github actions variables.

you have secreate key and access keyalreay , so add there.

7. Create infra using Terraform

Make sure Terraform is installed on your local system. Use the link to install according to your system

https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli

brew install terraform # On Mac
terraform workspace new ap-south-1
terraform workspace select ap-south-1
terraform init
terraform plan
terraform apply -auto-approve

9. GitHub Actions (Build and Deploy)

name: Deploy to Amazon ECS Fargate
on:
push:
branches:
- main
env:
AWS_REGION: ap-south-1 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY: django-app # set this to your Amazon ECR repository name
ECS_SERVICE: ecs-service # set this to your Amazon ECS service name
ECS_CLUSTER: ecs-cluster # set this to your Amazon ECS cluster name
ECS_TASK_DEFINITION: ecs-app-task # set this to the path to your Amazon ECS task definition
# file, e.g. .aws/task-definition.json
CONTAINER_NAME: django-app # set this to the name of the container in the
# containerDefinitions section of your task definition
permissions:
contents: read
jobs:
build-and-push:
name: Build and Push
runs-on: self-hosted
# environment: production
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: production
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f ./Dockerfile .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_ENV deploy:
name: Deploy
runs-on: self-hosted
needs: build-and-push

steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy Amazon ECS task definition
run:
aws ecs update-service --cluster $ECS_CLUSTER --no-paginate --service $ECS_SERVICE --force-new-deployment

9. Add SSL and domain.

To set up domain and SSL, use this video.

--

--