Design → Build → Prove. A production-grade, 3-tier web app deployed to AWS with Terraform and a GitHub Actions CI/CD pipeline — built the way a senior engineer would.
📺 Watch the build: devopsbymuh on YouTube · 📖 Deep dive: blog article · 🎯 This is Project 1 of the 10-project series
Note
TaskFlow is a small SaaS task-board app. The app itself is deliberately simple — the point of this repo is everything around it: the architecture, the infrastructure as code, the pipeline, and the production practices. You'll run it locally in one command, then deploy the exact same app to AWS.
A classic 3-tier design across two Availability Zones — the foundational pattern every later project in the series is a variation of.
flowchart TB
User([👤 User]) --> CF[CloudFront CDN]
CF -->|static SPA| S3[(S3 · React build)]
CF -->|/api/*| ALB[Application Load Balancer]
subgraph AWS VPC
subgraph "Public subnets (2 AZs)"
ALB
end
subgraph "Private subnets (2 AZs)"
ECS1[ECS Fargate · FastAPI]
ECS2[ECS Fargate · FastAPI]
end
subgraph "Private DB subnets (2 AZs)"
RDS[(RDS Postgres · Multi-AZ)]
end
end
ALB --> ECS1 & ECS2
ECS1 & ECS2 --> RDS
| Tier | Responsibility | AWS service | Runs locally as |
|---|---|---|---|
| Presentation | Serve the static React SPA | S3 + CloudFront | nginx container |
| Application | Stateless REST API | ECS Fargate + ALB | FastAPI container |
| Data | Durable, highly-available state | RDS Postgres (Multi-AZ) | Postgres container |
Full reasoning — why ECS Fargate over EKS, why Multi-AZ, how the health check drives failover — is in docs/system-design.md and the Architecture Decision Records.
Prerequisites: Docker + Docker Compose.
git clone https://github.com/devopsbymuh/aws-3tier-devops-project.git
cd aws-3tier-devops-project
docker compose up --buildThen open:
| URL | What |
|---|---|
| http://localhost:8080 | TaskFlow app (frontend) |
| http://localhost:8000/docs | API — interactive Swagger docs |
| http://localhost:8000/health | Health check (what the ALB probes) |
The database is auto-seeded with demo tasks on first run, so the board looks alive immediately. Stop with Ctrl+C; wipe the DB with make reset.
- Frontend: React 18 + Vite (static SPA → S3/CloudFront)
- Backend: FastAPI + SQLAlchemy 2.0 (stateless → ECS Fargate)
- Database: PostgreSQL 16 (→ RDS Multi-AZ)
- Infra: Terraform · CI/CD: GitHub Actions → ECR → ECS
- Local: Docker Compose
aws-3tier-devops-project/
├── app/
│ ├── backend/ # FastAPI service (Dockerfile, tests)
│ │ └── app/ # main, models, schemas, crud, routers, seed
│ └── frontend/ # React + Vite SPA (Dockerfile, nginx.conf)
├── infra/ # Terraform for the AWS 3-tier stack (built on camera)
├── docs/
│ ├── system-design.md # the "learn to think" writeup
│ ├── adr/ # Architecture Decision Records
│ └── images/ # diagram + screenshots
├── .github/workflows/ # CI/CD pipeline (built on camera)
├── docker-compose.yml # one-command local stack
└── Makefile # up · test · deploy · destroy
make up # build & run the full stack
make test # backend tests (in-memory SQLite — no DB needed)
make reset # wipe the local database volume
make deploy # terraform apply (provision on AWS)
make destroy # tear down ALL AWS resources — no surprise bill
make help # list everything| Method | Path | Description |
|---|---|---|
GET |
/health |
Liveness + DB readiness (ALB target) |
GET |
/api/tasks |
List tasks (?status= / ?priority= filters) |
POST |
/api/tasks |
Create a task |
GET |
/api/tasks/{id} |
Get one task |
PATCH |
/api/tasks/{id} |
Update a task |
DELETE |
/api/tasks/{id} |
Delete a task |
GET |
/api/stats |
Counts by status |
Interactive docs at /docs when running.
The infrastructure is built step by step in the video — this repo is tagged so you can jump to any stage and follow along:
| Tag | Stage | What exists |
|---|---|---|
v1-app |
The app | Runs locally with Docker Compose |
v2-terraform |
Infrastructure | VPC, ALB, ECS, RDS via Terraform |
v3-cicd |
Pipeline | GitHub Actions → ECR → ECS on every merge |
git checkout v2-terraform # land exactly where the video isImportant
This stack uses services outside the AWS Free Tier (ALB, NAT Gateway, RDS). Rough cost if left running:
| Resource | ~ Cost |
|---|---|
| ALB | ~$16/mo |
| NAT Gateway | ~$32/mo |
RDS db.t4g.micro Multi-AZ |
~$25/mo |
| ECS Fargate (2 small tasks) | ~$15/mo |
| Total | ~$90/mo if left on 24/7 |
Always tear down when you're done:
make destroymake destroy removes every billable resource. Spin it up, follow the video, prove it works, then destroy it — a few hours costs cents.
This project is designed to be talked about, not just built. See docs/system-design.md for how to present this architecture in a system-design interview — the trade-offs, the failure modes, and the "why" behind every box.
Issues and PRs welcome — see CONTRIBUTING.md.
MIT © Muhammad Rashid (devopsbymuh)
⭐ If this helped, star the repo — it helps others find it.