DevOps Project: The Plan
In this project you build a delivery pipeline for a small web API:
- a CRUD API in Python, in its own GitHub repository;
- a GitHub Actions pipeline:
- a push to your own branch runs the fast tests;
- a pull request runs more: integration tests, security and code inspection tools;
- a pull request waits for an approver before it can merge;
- a merge to
mainbuilds a container image and deploys it;
- a deployment on AWS: an EKS cluster, or a set of EC2 instances.
See the finished pipeline at work, one event at a time, in The Pipeline, Step by Step.
The tracks
Choose one of each pair when you start, and follow its steps only.
The API framework
- Flask: the basic track.
- Each request runs a plain function, start to finish, in a worker of its own.
- Plain Python is all it takes.
- FastAPI: the advanced track.
- It checks each request against declared types, and generates an OpenAPI page from them.
- It is built on
asyncio: a route may be anasync def, run on the server's one event loop.- An
awaithands the loop to another request while this one waits. - A blocking call inside an
async def(atime.sleep, a synchronous database driver) stops every request.
- An
- Choose it if you know
async/awaitand the event loop, or want to learn them on the way.
The deployment target
- EKS: the main track.
- A Kubernetes cluster: the deployment is a Deployment and a Service, the way most teams ship containers.
- It costs money from the moment it exists, whether the app runs or not.
- Created at the start of each working session and destroyed at its end, it costs about $13–$37 in all for 20–30 hours a month over 2–4 months: the computation is in Task 5.
- Left running, it costs about $200 a month.
- EC2: a set of instances running the container, for students who find EKS too hard.
- Fewer parts to learn, and only the instances and the load balancer to pay for.
- The deploy is your own script, where EKS gives you rollouts and health checks.
The app runs in a container on both targets.
Working alone or in a pair
The project is done alone or by two students sharing one repository. Choose when you start.
- In both, the way changes reach
mainchanges at Task 3:- Tasks 1–2: you push straight to
main. Nothing protects it yet, and the empty pipeline is easiest to watch that way. - From Task 3 on:
mainis protected. Every change goes on a branch of its own, through a pull request, and is merged only once its checks pass and it is approved.
- Tasks 1–2: you push straight to
- The difference is who approves.
- Either way, every branch follows one naming scheme: see Topic branches.
Alone
- Every issue is assigned to you, and every branch is yours.
- The approver is
pr-reviewer, the GitHub App: it stands in for the second person.- It approves after a round of requested changes, and never reads the code.
- The review is a formality; the checks are what stop a broken change.
- AWS: your own account.
In a pair
- One repository: one student creates it, and adds the other as a collaborator with write access.
- Every task together, both tracks shared: you choose Flask or FastAPI, EKS or EC2, once for the pair.
- Each issue is assigned to one of you: the assignee owns its branch, so a branch's owner is plain to both.
- The other student approves: GitHub never lets the author of a pull request approve it.
- Read the change before approving: this is the review
pr-revieweronly imitates. - Take turns: one writes a task's change, the other reviews it, and the next task swaps.
pr-revieweris still installed in Task 3, so the pipeline is the same as alone; either approval merges.
- Read the change before approving: this is the review
- Never push straight to
mainafter Task 3, even to fix the other's mistake: open a pull request. - One AWS account, the repository owner's. The pipeline deploys with its own role, so the other student needs console access only to look: TODO: an IAM user with read-only access, or IAM Identity Center.
- Split the AWS cost: the cluster's hours are the pair's hours, so one cluster costs no more than alone.
Topic branches
Every change starts as a GitHub issue, and its branch is named <type>/<issue>-<what>.
| Part | Holds | Example |
|---|---|---|
| type | feature for new behaviour of the API, fix for a bug, ci for the pipeline: workflows, Dockerfile, infrastructure | feature |
| issue | the issue's number | 12 |
| what | a few words, lowercase, joined by hyphens | search-books |
1$ git switch -c feature/12-search-books
2$ git push -u origin feature/12-search-books
- The number links everything: the branch names the issue, the pull request's description says
Closes #12, and the merge closes the issue. - The type groups the branches: GitHub's branch list and a workflow's
branches:filter can matchfix/**. - The words say what it is without opening the issue.
- One issue, one branch, one pull request; the branch is deleted after the merge.
The finished pipeline
The Pipeline, Step by Step plays all of it, one event at a time: a push to
a topic branch, a pull request through its checks and its review, the merge and the delivery, and a refused push to
main.
| Event | Jobs |
|---|---|
| Push to your branch | lint, unit tests |
Pull request to main | lint, unit tests, integration tests, security and code inspection, image build; then the approver's review |
Merge to main | image build and push, deploy, smoke test |
The order of the tasks
The tasks build the whole pipeline first, then fill it in.
- Tasks 1–3: the pipeline, empty.
- Every job exists from Task 2 on, as a placeholder that prints what it will do.
- You see each event run its jobs, and the approver gate the merge, before any job does real work.
- Tasks 4–6: the first complete solution.
- The placeholders for the image and the deployment become real.
- A merge to
mainputs the app on AWS.
- Tasks 7–10: the details.
- Each task replaces more placeholders, or makes a working job stricter.
Before you start
- A GitHub account.
- An AWS account, from Task 5 on. The infrastructure costs money while it runs; Task 11 removes it.
- A Docker Hub account, from Task 4 on.
- Python 3.12 or newer, Docker and git on your machine.
The site's other material, used along the way:
- GitHub Actions Workflows: an Introduction
- Pipeline Identities: the credentials the pipeline uses
- Git Collaboration: pull requests, review and branch protection