In this tutorial, we’ll look at how to deploy a Django app to AWS ECS with Terraform.

Dependencies:

  1. Django v3.1
  2. Docker v19.03.12
  3. Python v3.8.5
  4. Terraform v0.13.0

Objectives

By the end of this tutorial, you will be able to:

  1. Explain what Terraform is and how you can use it to write infrastructure as code
  2. Utilize the ECR Docker image registry to store images
  3. Create the required Terraform configuration for spinning up an ECS cluster
  4. Spin up AWS infrastructure via Terraform
  5. Deploy a Django app to a cluster of EC2 instances manged by an ECS Cluster
  6. Use Boto3 to update an ECS Service
  7. Configure AWS RDS for data persistence
  8. Create an HTTPS listener for an AWS load balancer

Terraform

Terraform is an infrastructure as code (IaC) tool used for building, changing, and versioning infrastructure through code. It uses a high-level declarative configuration language that lets you describe the desired state of your cloud or on-prem infrastructure for running an application. Think of it as the single source of truth for your infrastructure, which makes it easy to create, update, and delete resources safely and efficiently. After describing the end state of your infrastructure, Terraform generates a plan and then executes it – e.g., provision and spin up the necessary infrastructure.

If you’re new to Terraform, review the Introduction to Terraform article and go through the Getting Started guide.

In this tutorial, using Terraform, we’ll develop the high-level configuration files required to deploy a Django application to ECS. Once configured, we’ll run a single command to set up the following AWS infrastructure:

  • Networking:
  • VPC
  • Public and private subnets
  • Routing tables
  • Internet Gateway
  • Key Pairs
  • Security Groups
  • Load Balancers, Listeners, and Target Groups
  • IAM Roles and Policies
  • ECS:
  • Task Definition (with multiple containers)
  • Cluster
  • Service
  • Launch Config and Auto Scaling Group
  • RDS
  • Health Checks and Logs

Amazon’s Elastic Container Service (ECS) is a fully managed container orchestration platform that’s used to manage and run containerized applications on clusters of EC2 instances.

If you’re new to ECS, it’s recommended to experiment with it in the web console first. Rather than configuring all the underlying network resources, IAM roles and policies, and logs manually, let ECS create these for you. You’ll just need to set up ECS, a Load Balancer, Listener, Target Group, and RDS. Once you feel comfortable then move on to an infrastructure as code tool like Terraform.

Architecture diagram:

AWS Architecture Diagram

Project Setup

Let’s start by setting up a quick Django project.

Create a new project directory along with a new Django project:

$ mkdir django-ecs-terraform && django-ecs-terraform
$ mkdir app && cd app
$ python3.8 -m venv env
$ source env/bin/activate

(env)$ pip install django==3.1
(env)$ django-admin.py startproject hello_django .
(env)$ python manage.py migrate
(env)$ python manage.py runserver

Navigate to http://localhost:8000/ to view the Django welcome screen. Kill the server once done, and then exit from the virtual environment. Go ahead and remove it as well. We now have a simple Django project to work with.

Add a requirements.txt file:

Django==3.1
gunicorn==20.0.4

Add a Dockerfile as well:

## pull official base image
FROM python:3.8.5-slim-buster

## set work directory
WORKDIR /usr/src/app

## set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

## install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt

## copy project
COPY . .

For testing purposes, set DEBUG to True and allow all hosts in the settings.py file:

DEBUG = True

ALLOWED_HOSTS = ['*']

Next, build and tag the image and spin up a new container:

$ docker build -t django-ecs .

$ docker run \
    -p 8007:8000 \
    --name django-test \
    django-ecs \
    gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000

Ensure you can view the welcome screen again at http://localhost:8007/.

Stop and remove the container once done:

$ docker stop django-test
$ docker rm django-test

Add a .gitignore file to the project root:

__pycache__
.DS_Store
*.sqlite3

Your project structure should now look like this:

├── .gitignore
└── app
    ├── Dockerfile
    ├── hello_django
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── manage.py
    └── requirements.txt

For a more detailed look at how to containerize a Django app, review the Dockerizing Django with Postgres, Gunicorn, and Nginx blog post.

#django

Deploying Django to AWS ECS with Terraform
14.35 GEEK