Back to Blog
May 6, 20246 min read

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

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

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.

💬 Got questions? Ask me anything!