Proyecto de práctica que implementa un ciclo de vida DevOps completo: desde el desarrollo de una API REST con FastAPI, pasando por la containerización con Docker, la infraestructura como código con Terraform, hasta el CI/CD automatizado con GitHub Actions.
Objetivo: Practicar el flujo completo de DevOps utilizando herramientas modernas como AWS (simulado con LocalStack), Docker y Terraform.
DevOps-API-Project/
├── app/
│ ├── main.py # API FastAPI
│ └── requirements.txt # Dependencias Python
├── infra/
│ ├── main.tf # Recursos AWS (EC2 + Security Group)
│ └── provider.tf # Configuración del provider AWS
├── .github/
│ └── workflows/
│ └── deploy.yml # Pipeline CI/CD
├── Dockerfile # Imagen multi-stage de la API
├── .gitignore
└── README.md
| Área | Herramienta |
|---|---|
| API | FastAPI + Uvicorn |
| Containerización | Docker (multi-stage build) |
| Cloud (simulado) | LocalStack |
| Infraestructura como Código | Terraform + tflocal |
| CI/CD | GitHub Actions |
| Registro de Imágenes | Docker Hub |
Código ──► Docker Build ──► Terraform Validate ──► Push a DockerHub ──► Deploy en Servidor
│ │ │ │ │
app/ Dockerfile infra/*.tf GitHub Actions SSH + docker run
La API tiene dos endpoints básicos:
| Método | Endpoint | Descripción |
|---|---|---|
GET |
/ |
Estado general de la API |
GET |
/health |
Health check |
pip install -r app/requirements.txt
uvicorn app.main:app --reloadLa imagen usa un build multi-stage para mantener la imagen final lo más liviana posible:
- Stage
builder: Instala dependencias en un entorno virtual (/opt/venv) - Stage final (runtime): Solo copia el
venvy el código — sin herramientas de compilación
# Construir la imagen
docker build -t mi-api-dev .
# Correr el contenedor
docker run -d -p 8080:8000 mi-api-dev:latest
# Acceder a la API
curl http://localhost:8080/healthSeguridad: El contenedor corre con un usuario sin privilegios de root (
appuser) y escucha en el puerto8000para evitar requerir permisos elevados.
La infraestructura en infra/ define en AWS:
- Security Group con acceso HTTP (puerto 80) y SSH (puerto 22)
- Instancia EC2
t2.micro
Se utiliza LocalStack para simular los servicios de AWS localmente sin costo.
# Instalar terraform-local
pipx install terraform-local
# Iniciar LocalStack con Docker
docker run -d --name localstack -p 127.0.0.1:4566:4566 localstack/localstackcd infra/
# Inicializar providers
tflocal init
# Ver qué se va a crear
tflocal plan
# Crear la infraestructura en LocalStack
tflocal apply
# Verificar la instancia EC2 creada
aws --endpoint-url=http://localhost:4566 ec2 describe-instances
# Destruir la infraestructura
tflocal destroyEl pipeline en .github/workflows/deploy.yml se ejecuta automáticamente en cada push a main y tiene dos jobs encadenados:
Valida la sintaxis de los archivos .tf antes de cualquier otra acción.
terraform init (sin backend) → terraform validate
Solo se ejecuta si el Job 1 pasa exitosamente.
Login DockerHub → Build & Push imagen → SSH al servidor → docker pull y run
Ve a Settings → Secrets and variables → Actions y agrega:
| Secret | Descripción |
|---|---|
DOCKERHUB_USERNAME |
Tu usuario de Docker Hub |
DOCKERHUB_TOKEN |
Token de acceso de Docker Hub |
SERVER_HOST |
IP o dominio de tu servidor |
SERVER_USERNAME |
Usuario SSH del servidor |
SERVER_SSH_KEY |
Clave privada SSH (contenido del archivo ~/.ssh/id_rsa) |
- ✅ FastAPI — desarrollo de APIs REST en Python
- ✅ Docker multi-stage build — optimización de imágenes
- ✅ Seguridad en contenedores — usuario no-root, puertos seguros
- ✅ Terraform IaC — definición de infraestructura como código (HCL)
- ✅ Security Groups en AWS — control de tráfico ingress/egress
- ✅ LocalStack — simulación de AWS en local sin costo
- ✅ GitHub Actions — automatización de CI/CD
- ✅ Docker Hub — registro y distribución de imágenes
Benja — Aprendiendo DevOps en la práctica 🚀