This project's main objective is to provide Django developers with an easy way of deploying several Django projects on AWS.
Technologies used:
- Pulumi
- AWS
Components per Django project:
- 1 Application Load Balancer (ALB)
- 1 ECS Service
- N tasks per service (parametrized)
- 1 RDS Database
- django_services: Django projects implemented.
- <django_project_name>:
- ...
- management: app that must be copied and installed into any new project. Used to be able to use custom admin commands.
- entrypoint.sh: must be copied into any new project. Used to initialize the server correctly on AWS.
- Dockerfile: must be copied into any new project. Used to deploy the server on AWS with all the necessary dependencies.
- requirements.txt: must be included with the necessary dependencies for each Django project + gunicorn==21.2.0 + boto3==1.34.55.
- <django_project_name>:
- pulumi: Infrastructure as Code that deploys the infrastructure needed for each Django project.
- Pulumi.main.yaml: config file to let Pulumi know of the characteristics of each of your projects (cpu, memory, number of workers, DB preferences...)
The following explains the IaC config file where you would need to fill in your project's settings:
config:
aws:region: eu-west-1
vpc_name: type = str
add_nat: type = bool, Optional
django_services: type = dict, Optional
<django_project_1>:
backend:
django_project: type = str
cpu: type = int, Optional (default = 256). The hard limit of CPU units to present for the task. Expressed using CPU units.
memory: type = int, Optional (default = 512). The hard limit of memory (in MiB) to present to the task.
desired_count: type = int, Optional (default = 1). Number of instances of the task definition to place and keep running.
workers_per_instance: type = int, Optional (default = 1). Number of Django workers per instance.
lb_port: type = int, Optional (default = 80). Load Balancer port.
container_port: type = int, Optional (default = 8000). Container port.
superuser:
username: type = str. Superuser user name.
email: str. Superuser email.
db:
engine: type = str. The AWS RDS engine. Options: aurora-mysql or aurora-postgresql
family: type = str. The AWS RDS family.
version: type = str. The AWS RDS engine version.
db_name: type = str. DB name to hold Django ORM and internal tables.
port: type = int. DB port.
<django_project_2>:
...Some things to take into account before developing with this repo:
- This repo is not production ready:
- The service doesn't autoscale horizontally, it needs an Auto Scaling Group in AWS to do so.
- The web page uses HTTP, so the communication is not encrypted.
- You must add the management app stored in the sample project to every new project. This is to be able to use custom commands internally. It's important that you remember to install the app in your settings.py project's file.
- You must also add the Dockerfile and the entrypoint.sh to every new Django project.
- You must copy the code used in settings.py to access DB secrets in new projects. This is to access the DB secrets in a secure manner, through AWS Parameter Store.
- When deploying locally the Django server will use the SQLite3 DB and will ignore the db config stated in the IaC config. When deploying with Pulumi the Django server will use the config stated in the IaC Config.
-
You must own an AWS account and have an Access Key to be able to authenticate. You need this so every script or deployment is done with the correct credentials. See here steps to configure your credentials.
-
Versions:
- Pulumi >=3.0.0,<4.0.0
- Python = 3.11
python3 -m venv .venv
source .venv/bin/activateIn the case of using Microsoft:
python3 -m venv .venv
.\env\Scripts\activateAnd to install all required packages:
pip install -r requirements.txtNavigating to the pulumi directory:
cd pulumi
pulumi upYou will enter a dialog where it will ask you if you want to create a stack. Check the pulumi docs for details.
Once you deploy you will se the following outputs:
- Load Balancer DNS: to be able to connect to your deployed app.
- Passwords parameter name: name of the parameter that holds the passwords for the Django super user and the DB admin.
Example:

