1.Project 1 — A Production Django API
The first project is the one most backend engineers are actually asked to build: a containerised Django API behind a load balancer, with a managed database, a cache, object storage and no secrets in the image. Build it in seven milestones, and finish each one with something you can demonstrate rather than something you have configured.
Key features
- Two task definitions, not one: the web tasks run gunicorn behind the load balancer, the worker tasks run Celery and sit behind no listener at all
- The execution role pulls the image and reads the secrets; the task role is what the application code itself uses — they are different roles for a reason
- Migrations run as a one-off task before the new service revision rolls, so a failed migration stops the release instead of racing four starting containers
- Secrets are referenced by ARN in the task definition and injected at start; the value never appears in the image, the repository or the environment block of a template
- Static files go to S3 behind CloudFront and user uploads go to a separate bucket, because they have different access rules and different lifecycle needs
- The health check path must touch the database, or a task with an exhausted connection pool keeps receiving traffic
Seven milestones, each ending in something you can demonstrate
- An architecture diagram of a Django API on AWS, read top to bottom.
- A browser resolves the domain through Route 53 and reaches an Application Load Balancer in the public subnets across two Availability Zones.
- The load balancer forwards to ECS Fargate web tasks in private subnets, running gunicorn, spread across the same two zones.
- The web tasks read and write RDS PostgreSQL with a Multi-AZ standby, use ElastiCache Redis for caching and sessions, and put user uploads into an S3 bucket.
- A separate set of ECS worker tasks runs Celery, consumes from the same Redis or an SQS queue, and has no load balancer in front of it.
- Secrets Manager supplies the database password and API keys to both task sets at start time, by ARN.
- CloudWatch collects logs, metrics and alarms from every component.
- A one-off migration task runs before the new service revision rolls out; static assets are served from S3 through CloudFront.
Signature
Route 53 → ALB → ECS (web + workers) → RDS + Redis + S3, secrets by ARN, migrations as a gated task
Build outside-in: a reachable hello-world before anything else, then the database, then secrets by ARN, then migrations as their own gated task, then cache and storage, then workers and alarms. Two roles, two services, two scaling signals — and a health check that touches the database.