University of Amsterdam
In this tutorial, we use GitOps practices with FastAPI, including CI/CD pipelines, code quality tools, and automated testing.
-
FastAPI
-
GitOps
-
Code Quality
-
Testing
-
Docker
-
Kubernetes & Helm
The steps of this tutorial are as follows:
- Building REST APIs with FastAPI
- Testing
- Code Quality
- Pre-commit Hooks
- Docker
- Minikube Setup
- Kubernetes Deployment with Helm
Prerequisites:
- Python 3.11 or higher
- Git
- Docker (optional, for containerization)
- GitHub account
-
Clone the Repository:
git clone https://github.com/DevOps-and-Cloud-based-Software/fastapi-gitops.git cd fastapi-gitops-starter -
Set Up the Python Environmentt:
# Create a virtual environment python -m venv venv # Activate the virtual environment # On Linux/MacOS: source venv/bin/activate # On Windows: venv\Scripts\activate # Install dependencies pip install -r requirements.txt
-
Run the Application:
uvicorn app.main:app --reload
-
Visit http://localhost:8000 to verify that the API is running.
-
Explore the API:
- API Documentation: http://localhost:8000/GitOps-Starter/docs
- Root endpoint: http://localhost:8000/GitOps-Starter
- Health check: http://localhost:8000/GitOps-Starter/health
- List items: http://localhost:8000/GitOps-Starter/api/items
- Retrieve a specific item: http://localhost:8000/GitOps-Starter/api/items/1
-
Run Tests:
pytest
- Run Tests with Coverage:
pytest --cov=app --cov-report=html
-
Open
htmlcov/index.htmlin a browser to view the coverage report.
-
Linting with Ruff:
# Check for issues ruff check app/ tests/ # Fix auto-fixable issues ruff check app/ tests/ --fix
-
Code Formatting with Black
# Check formatting black --check app/ tests/ # Format code black app/ tests/
Pre-commit hooks automatically run checks before each commit to ensure consistent code quality.
-
Setup Pre-commit:
# Install pre-commit pip install pre-commit # Install the git hooks pre-commit install
-
Using Pre-commit:
Pre-commit will now run automatically on
git commit. You can also run it manually:# Run on all files pre-commit run --all-files # Run on staged files pre-commit run
-
The pre-commit hooks include:
- Trailing whitespace removal
- End of file fixer
-
Build the Docker Image:
docker build -t fastapi-gitops-starter . -
Run the Container:
docker run -p 8000:8000 fastapi-gitops-starter
-
Access the API at http://localhost:8000/GitOps-Starter/
To test the Kubernetes deployment locally, use Minikube.
-
Install Minikube: Follow the instructions at the Minikube installation guide.
-
Start Minikube with Ingress and Ingress-DNS Addons:
minikube start --addons=ingress,ingress-dns
-
Add Minikube IP to /etc/hosts:
-
Get the Minikube IP:
minikube ip
-
Add the following line to your
/etc/hostsfile:<MINIKUBE_IP> minikube.testReplace
<MINIKUBE_IP>with the IP address obtained from the previous command.
This repository includes a Helm chart for deploying the application to Kubernetes.
-
Prerequisites
- Kubernetes 1.19+
- Helm 3.0+
-
Install the Helm Chart:
helm install my-release ./helm/fastapi-gitops-starter
-
Uninstall the Helm Chart:
helm uninstall my-release
Refer to helm/README.md for additional configuration options.
Make sure you understand how to set up the Horizontal Pod Autoscaler (HPA) for
scaling based on load and ingress configuration for accessing the application
including host and paths.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Ensure all tests pass and code quality checks are successful
- Merge
- Open
.pre-commit-config.yaml - Add a new hook to check:
- To prevent committing large files
- To check YAML files for syntax errors (excluding Helm charts)
- To sort imports in Python files
- To check for security issues
- To make sure we do not commit secrets
- To check code style
- Open
app/main.py - Add a new endpoint to create an item:
@app.post("/api/items")
async def create_item(name: str, description: str):
"""Create a new item."""
return {
"id": 999,
"name": name,
"description": description,
"created": True
}- Write a test in
tests/test_main.py - Run tests to verify
- Open
.github/workflows/ci-cd.yml - Add a step to lint the code using Ruff
- Add a step to run tests with coverage. The pipeline should fail if coverage is below 80%
- Add a step to build the Docker image if tests pass. If we do a release, tag the image appropriately (with its version and the tag 'latest') and push it to GitHub registry
- Set up a Kubernetes cluster (e.g., using Minikube or a cloud provider)
- Deploy the application using the Helm chart
- Set up the scaling parameters in
custom-values.yamlto handle more load by enabling Horizontal Pod Autoscaler (HPA). Set targetCPUUtilizationPercentage to 10% - Perform a load test using
hey
hey -z 30s http://minikube.test/GitOps-Starter/api/items
- Monitor the scaling of pods in the cluster:
kubectl get hpa -n default -w- Note how much time it takes for the pods to scale up and down based on the load
- The auto-scaling did not work as expected. What could be the possible reasons?
- How does Horizontal Pod Autoscaling (HPA) work in Kubernetes?