In this tutorial, we’ll look at how to deploy a Django app to AWS ECS with Terraform.
Dependencies:
By the end of this tutorial, you will be able to:
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:
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:
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