La solución DevOps del assesment assets/"Assessment - DevOps.pdf está compuesta por dos repositorios que trabajan en conjunto para desplegar una aplicación sobre Azure:
- Azure Resource Groups: Separación lógica entre entornos
DEVyPROD. - Azure Kubernetes Service (AKS): Clúster gestionado para orquestar contenedores.
- Azure Container Registry (ACR): Almacén privado para imágenes Docker.
- GitHub Actions con OIDC: Integración segura para despliegues automatizados sin secretos estáticos.
https://github.com/hsniama/infra-devops
- FastAPI + Redis: Microservicio con control de unicidad de JWT mediante Redis.
- CI/CD con GitHub Actions: Pipeline automatizado para construir, testear y desplegar.
- Ingress-nginx: Controlador de entrada HTTP para enrutar tráfico hacia los pods.
- Cert-manager + Let's Encrypt: Emisión automática de certificados TLS reales en
PROD. - DuckDNS: Resolución de dominio público para exponer el servicio externamente
https://github.com/hsniama/app-devops
- Todo el tráfico externo en
PRODse enruta por HTTPS con certificados válidos. - En
DEV, se permite tráfico HTTP para facilitar pruebas locales.
El flujo correcto es Infra → App.
- Programación: Python con FastAPI
- Contenerización: Docker
- IaC: Cloud Azure
- CI/CD: GitHub Actions
Una ves hallamos desplegado primero la infraestructura del proyecto mediante el Repositorio: https://github.com/hsniama/infra-devops, vamos a entender más a fondo este repositorio de la aplicación.
Este repo contiene:
- Microservicio FastAPI
- Dockerfile hardened (non-root)
- Manifests Kubernetes
- Pipeline CI/CD completo
- Despliegue automático a AKS
- API Key vía header
- JWT firmado (SH256)
- JWT válido una sola vez (one-time token)
- Expiración real del JWT
- Redis para control de unicidad en Kubernetes
- TLS con Let’s Encrypt PROD
- Secrets gestionados con:
- GitHub Environments
| Rama Git | Ambiente | Namespace | Host público |
|---|---|---|---|
dev/** |
DEV | devops-dev |
henrydevops-dev.duckdns.org |
main (merge) |
PROD | devops-prod |
henrydevops-prod.duckdns.org |
- DEV: despliegue automático desde cualquier rama
dev/** - PROD: solo se despliega al hacer merge a
main
Método: GET
Endpoint: /generate-jwt
Devuelve un JWT válido una sola vez por transacción.
Método: POST
Endpoint: /DevOps
Headers requeridos:
X-Parse-REST-API-KeyX-JWT-KWY
Abrir una terminar Unix:
Si es para DEV:
HOST="henrydevops-dev.duckdns.org"Si es para PROD: (previo despliege)
HOST="henrydevops-prod.duckdns.org"JWT="$(curl -sk https://${HOST}/generate-jwt | sed -E 's/.*"jwt":"([^"]+)".*/\1/')" curl -sk -X POST \
-H "X-Parse-REST-API-Key: 2f5ae96c-b558-4c7b-a590-a501ae1c3f6c" \
-H "X-JWT-KWY: ${JWT}" \
-H "Content-Type: application/json" \
-d '{"message":"This is a test","to":"Juan Perez","from":"Rita Asturia","timeToLifeSec":45}' \
"https://${HOST}/DevOps"Respuesta esperada:
{
"message": "Hello Juan Perez your message will be send"
}
Repetir el POST con el mismo JWT devuelve:
{
"detail": "Invalid or missing JWT"
}
Ejemplo práctico:
El pipeline se ejecuta usando OIDC (no secrets de Azure) para autenticar GitHub Actions contra Azure.:
- Lint (flake8)
- SAST (bandit)
- Tests (pytest + coverage)
- Build Docker
- Push a ACR
- Deploy a AKS
- Smoke test vía HTTPS
No necesariamente necesitas modificar algo en la rama dev/**, se puede correr el workflow de forma manual:
Esta solución cumple:
- Infraestructura como código
- CI/CD
- HTTPS válido (para prod)
- Escalabilidad
- Separación DEV / PROD
La solución es reproducible desde cero siguiendo el:
- EXECUTION.md README


