A small Flask app with a fully automated CI/CD pipeline: every push to main runs tests, builds a Docker image, pushes it to Amazon ECR, and deploys it to AWS ECS Fargate — with zero manual steps.
git push
│
▼
┌─────────────┐ ┌──────────────────┐ ┌───────────────┐
│ Run tests │ ──▶ │ Build & push image│ ──▶ │ Deploy to ECS │
│ (pytest) │ │ to Amazon ECR │ │ Fargate │
└─────────────┘ └──────────────────┘ └───────────────┘
GitHub Actions GitHub Actions GitHub Actions
If tests fail, the pipeline stops there — nothing broken ever reaches production.
- Designing a multi-stage CI/CD pipeline (test → build → deploy) with GitHub Actions
- Containerizing an application with Docker
- Pushing images to a private container registry (Amazon ECR)
- Deploying containers to a serverless container platform (ECS Fargate — no EC2 servers to manage)
- Managing secrets and environment configuration securely in CI
Flask · Docker · GitHub Actions · Amazon ECR · Amazon ECS (Fargate) · pytest
Before the pipeline can deploy successfully, this AWS infrastructure needs to exist:
- An ECR repository named
ci-cd-flask-app - An ECS cluster named
ci-cd-flask-cluster(Fargate) - An ECS service named
ci-cd-flask-servicerunning on that cluster - A CloudWatch log group named
/ecs/ci-cd-flask-task - An IAM user with programmatic access and permissions for ECR + ECS (for GitHub Actions to authenticate as)
Quick way to create the core pieces via AWS CLI:
aws ecr create-repository --repository-name ci-cd-flask-app
aws ecs create-cluster --cluster-name ci-cd-flask-cluster
aws logs create-log-group --log-group-name /ecs/ci-cd-flask-task(Creating the ECS service itself needs a VPC/subnet/security group — reuse the ones from the terraform-aws-vpc-webserver project, or set them up via the ECS console the first time.)
Add these under Settings → Secrets and variables → Actions:
| Secret name | Value |
|---|---|
AWS_ACCESS_KEY_ID |
Access key for the IAM user |
AWS_SECRET_ACCESS_KEY |
Secret key for the IAM user |
docker build -t flask-app .
docker run -p 5000:5000 flask-app
# visit http://localhost:5000pip install -r app/requirements.txt -r tests/requirements-test.txt
pytest tests/ -v- Add a staging environment with manual approval before production deploy
- Add vulnerability scanning of the Docker image (e.g. Trivy) as a pipeline step
- Add Slack/email notifications on pipeline success or failure
- Provision the ECS cluster/service itself with Terraform instead of the AWS CLI
MIT