Minimal Django todo app with cookie-based authentication, PostgreSQL, and REST API.
- Install dependencies:
pip install -r requirements.txt- Setup PostgreSQL:
psql -U postgres -f setup.sql- Run migrations:
python manage.py migrate- Create superuser:
python manage.py createsuperuser- Run server:
python manage.py runserverSwagger UI is available at: http://localhost:8000/api/docs/
OpenAPI schema: http://localhost:8000/api/schema/
GET /auth/csrf/- Get CSRF tokenPOST /auth/login/- Login (sets cookies)POST /auth/refresh/- Refresh sessionPOST /auth/logout/- Logout
GET /me/- Current user profileGET/POST /lists/- Lists managementGET/PATCH/DELETE /lists/{id}/- List operationsGET/POST /todos/- Todos managementGET/PATCH/DELETE /todos/{id}/- Todo operationsPOST /todos/{id}/toggle/- Toggle todo statusPOST /todos/bulk/- Bulk operations
- Argon2 password hashing
- HttpOnly cookies
- CSRF protection
- Rate limiting
- Security headers (X-Frame-Options, etc.)
- Request validation
- Idempotency keys
- Reverse proxy with load balancing
- Static/media file serving
- Rate limiting (5/min login, 10/min auth, 100/min API)
- Security headers (X-Frame-Options, etc.)
- Gzip compression
./deploy.shAccess:
- Application:
http://localhost:80(via Nginx) - API Documentation:
http://localhost:80/api/docs/ - Direct Django:
http://localhost:8000(development only)
- Copy nginx config:
cp nginx/nginx.conf /etc/nginx/sites-available/todoapp - Enable site:
ln -s /etc/nginx/sites-available/todoapp /etc/nginx/sites-enabled/ - Restart nginx:
systemctl restart nginx
- AWS CLI configured with appropriate credentials
- Docker and Docker Compose installed
- Route53 hosted zone for
aidevstack.org
# Set AWS credentials
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_REGION=us-east-1
# Navigate to infra directory
cd infra/
# Initialize and apply setup (creates S3 bucket, DynamoDB table, IAM user for CD, and ECR repositories)
docker compose run --rm terraform -chdir=setup init
docker compose run --rm terraform -chdir=setup plan
docker compose run --rm terraform -chdir=setup apply
# Get CD user credentials (needed for CI/CD)
docker compose run --rm terraform -chdir=setup output cd_user_access
docker compose run --rm terraform -chdir=setup output -raw cd_user_access_key_secret
# Get ECR repository URLs
docker compose run --rm terraform -chdir=setup output ecr_repo_app
docker compose run --rm terraform -chdir=setup output ecr_repo_proxy
# Initialize and apply deployment infrastructure
export TF_WORKSPACE=dev # or staging/prod
docker compose run --rm terraform -chdir=deploy init
docker compose run --rm terraform -chdir=deploy workspace select -or-create $TF_WORKSPACE
docker compose run --rm terraform -chdir=deploy plan
docker compose run --rm terraform -chdir=deploy apply- S3 Bucket:
devops-todo-api-tf-statefor Terraform state storage - DynamoDB Table:
devops-todo-api-tf-lockfor state locking - IAM User:
todo-app-api-cdwith comprehensive policies for CI/CD access - ECR Repositories:
devops-todo-apifor application Docker imagesdevops-todo-proxyfor proxy Docker images
- IAM Policies: EC2, RDS, ECS, ELB, EFS, Route53, CloudWatch, and SSM access
Network Infrastructure:
- VPC: 10.1.0.0/16 with DNS support
- Public Subnets: 10.1.1.0/24, 10.1.2.0/24 (ALB access)
- Private Subnets: 10.1.10.0/24, 10.1.11.0/24 (ECS, RDS)
- Internet Gateway: Public internet access
- VPC Endpoints: ECR, CloudWatch, SSM, S3 (private access)
Database:
- RDS PostgreSQL 15.3: db.t4g.micro instance
- Multi-AZ: Disabled (cost optimization)
- Storage: 20GB GP2 with auto-scaling
- Security: VPC security groups, private subnets
Container Platform:
- Application Load Balancer: HTTP/HTTPS with SSL termination
- Target Groups: Health checks on
/api/health-check/ - Security Groups: Controlled access between services
Storage:
- EFS: Encrypted file system for media storage
- Access Points: Configured for application media
- Mount Targets: Multi-AZ availability
DNS & SSL:
- Route53: Domain management for
aidevstack.org - ACM Certificates: Automatic SSL certificate provisioning
- Subdomains:
api.aidevstack.org(prod)api.staging.aidevstack.org(staging)api.dev.aidevstack.org(dev)
infra/setup/variables.tf- S3 bucket and DynamoDB table namesinfra/deploy/variables.tf- Resource prefix (raa), project name, domain configurationinfra/docker-compose.yml- Terraform 1.6.2 container configurationinfra/deploy/templates/ecs/- ECS task role policies
Managed via Terraform workspaces with prefix raa-{workspace}:
- dev: Development environment (
api.dev.aidevstack.org) - staging: Staging environment (
api.staging.aidevstack.org) - prod: Production environment (
api.aidevstack.org)
# List workspaces
docker compose run --rm terraform -chdir=deploy workspace list
# Select workspace
export TF_WORKSPACE=dev
docker compose run --rm terraform -chdir=deploy workspace select $TF_WORKSPACEGitHub Actions Workflows:
checks.yml- PR validation (test and lint)deploy.yml- Automated deployment to staging/proddestroy.yml- Manual environment cleanuptest-and-lint.yml- Reusable test workflow
Required Secrets:
AWS_ACCESS_KEY_ID- CD user access keyAWS_SECRET_ACCESS_KEY- CD user secret keyTF_VAR_DB_PASSWORD- Database passwordTF_VAR_DJANGO_SECRET_KEY- Django secret keyDOCKERHUB_TOKEN- Docker Hub authentication
Required Variables:
ECR_REPO_APP- Application ECR repository URLECR_REPO_PROXY- Proxy ECR repository URLDOCKERHUB_USER- Docker Hub username
Production URLs:
- Production:
https://api.aidevstack.org - Staging:
https://api.staging.aidevstack.org - Development:
https://api.dev.aidevstack.org
API Documentation:
- Swagger UI:
https://{domain}/api/docs/ - OpenAPI Schema:
https://{domain}/api/schema/
Health Check:
- Health endpoint:
https://{domain}/api/health-check/
# Destroy deployment infrastructure (run for each workspace)
export TF_WORKSPACE=dev # or staging/prod
docker compose run --rm terraform -chdir=deploy destroy
# Destroy setup infrastructure (S3, DynamoDB, IAM, ECR)
docker compose run --rm terraform -chdir=setup destroy