A complete DevOps project featuring a FastAPI application with a live system metrics dashboard, infrastructure provisioning with Terraform, automated configuration with Ansible, and containerization with Docker.
- Overview
- Architecture
- Prerequisites
- Quick Start
- Local Development
- Docker
- Infrastructure Deployment
- API Reference
- Testing
- Makefile Commands
- Project Structure
- Contributing
- License
This project is a DevOps learning sandbox that demonstrates modern infrastructure and deployment practices. The application itself, a simple system metrics API, serves as a minimal but functional payload for the pipeline.
| Practice | Tool | Description |
|---|---|---|
| Infrastructure as Code | Terraform | Automated AWS provisioning |
| Configuration Management | Ansible | Zero-touch server setup |
| Containerization | Docker | Multi-stage builds for optimized images |
| CI/CD | GitHub Actions | Lint, test, build, and deploy pipeline |
| Monitoring | Gradio + Plotly | Real-time metrics dashboard |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub Actions β
β (Lint β Test β Build β Deploy) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β Terraform ββββββΆβ Ansible ββββββΆβ Application β
β (AWS EC2, SG) β β (Docker, Config) β β (FastAPI) β
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
- Python 3.11+
- uv - Fast Python package manager
- Docker - For containerization
- Terraform - For infrastructure provisioning
- Ansible - For configuration management
- AWS CLI - Configured with appropriate credentials
# Clone the repository
git clone git@github.com:lele-sf/fastapi-devops-pipeline.git
cd fastapi-devops-pipeline
# Install dependencies
uv sync
# Run the application
uv run uvicorn src.app.main:app --reloadOpen your browser:
- API: http://localhost:8000
- Docs: http://localhost:8000/docs
- Dashboard: http://localhost:8000/dashboard
# Install all dependencies (including dev)
uv sync
# Install pre-commit hooks
uv run pre-commit install
# Activate the virtual environment (optional, uv run handles this)
source .venv/bin/activate # Linux/macOS
# or
.venv\Scripts\activate # Windows# Development mode with auto-reload
uv run uvicorn src.app.main:app --reload
# Or using FastAPI CLI
uv run fastapi dev src/app/main.py# Build the image
docker build -t fastapi-devops-pipeline .
# Run the container
docker run -p 8000:80 fastapi-devops-pipelinedocker run -p 8000:80 <your-dockerhub-username>/fastapi-devops-pipeline:latestAccess the application at http://localhost:8000
cd infrastructure/terraform
# Copy the example file
cp terraform.tfvars.example terraform.tfvars
# Edit with your values
# - my_public_ip: Your IP in CIDR notation (e.g., "203.0.113.1/32")
# - ssh_public_key_path: Path to your SSH public keycd infrastructure/ansible
# Copy the example file
cp inventory-example.ini inventory.ini
# The deploy script will update the IP automatically# Make the script executable
chmod +x scripts/deploy.sh
# Run full deployment
./scripts/deploy.shThe deployment script will:
- β Provision AWS infrastructure with Terraform
- β Retrieve the EC2 public IP
- β Update Ansible inventory
- β Wait for SSH availability
- β Configure the server with Ansible
- β Deploy the application in Docker
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Welcome message |
/health |
GET | Health check endpoint |
/metrics |
GET | System metrics (CPU, memory, uptime) |
/dashboard |
GET | Interactive Gradio dashboard |
/docs |
GET | OpenAPI documentation (Swagger UI) |
/redoc |
GET | OpenAPI documentation (ReDoc) |
{
"uptime_seconds": 3600.25,
"memory_used_mb": 512.45,
"memory_total_mb": 2048.00,
"cpu_percent": 15.5,
"system": "Linux",
"architecture": ["64bit", "ELF"],
"timestamp": "2025-01-15T10:30:00+00:00"
}# Run all tests
uv run pytest
# Run with verbose output
uv run pytest -v
# Run with coverage
uv run pytest --cov=src/app
# Linting
uv run ruff check src/
# Format code
uv run ruff format src/
# Run pre-commit checks manually
uv run pre-commit run --all-filesRun make help to see all available commands:
make install # Install production dependencies
make install-dev # Install dev dependencies + pre-commit hooks
make test # Run tests
make test-cov # Run tests with coverage
make lint # Check code with ruff
make format # Format code with ruff
make run # Run FastAPI locally
make docker-build # Build Docker image
make docker-run # Run Docker container
make deploy # Full infrastructure deployment
make pre-commit # Run pre-commit hooks
make clean # Remove cache filesfastapi-devops-pipeline/
βββ .github/
β βββ workflows/
β βββ ci-cd.yaml # CI/CD pipeline configuration
βββ infrastructure/
β βββ ansible/
β β βββ inventory.ini # Server inventory (gitignored)
β β βββ inventory-example.ini
β β βββ playbook.yaml # Configuration playbook
β β βββ requirements.yml # Ansible collections
β βββ terraform/
β βββ ec2.tf # EC2 instance
β βββ key_pair.tf # SSH key pair
β βββ main.tf # Provider configuration
β βββ outputs.tf # Output values
β βββ security_group.tf # Security group rules
β βββ variables.tf # Variable definitions
β βββ terraform.tfvars.example
βββ scripts/
β βββ deploy.sh # Full deployment script
βββ src/
β βββ app/
β βββ __init__.py
β βββ main.py # FastAPI application entry
β βββ routes.py # API routes
β βββ schemas.py # Pydantic models
β βββ dashboard.py # Gradio dashboard
βββ tests/
β βββ __init__.py
β βββ conftest.py # Pytest fixtures
β βββ test_routes.py # API endpoint tests
βββ .gitignore
βββ .pre-commit-config.yaml # Pre-commit hooks
βββ .python-version
βββ Dockerfile # Multi-stage Docker build
βββ LICENSE
βββ Makefile # Development commands
βββ pyproject.toml # Project dependencies
βββ uv.lock # Locked dependencies
βββ README.md
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Ensure all pre-commit hooks pass (
uv run pre-commit run --all-files) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Note: Pre-commit hooks will automatically run on every commit. If any hook fails, the commit will be rejected and you'll need to fix the issues before committing again.
This project is licensed under the MIT License - see the LICENSE file for details.