Infraestructura y Despliegue (AWS Stack)
Este documento define la arquitectura de nube, la topología de red y el ciclo de vida de los microservicios en Go. La infraestructura se gestiona bajo el principio de Infrastructure as Code (IaC) para garantizar entornos replicables, seguros y escalables.
1. Topología de Red y Flujo de Tráfico
El sistema utiliza una arquitectura de VPC (Virtual Private Cloud) con aislamiento estricto mediante subredes públicas y privadas, protegiendo la persistencia de datos y los microservicios core.
2. Componentes del Stack AWS
| Servicio | Función | Detalle Técnico / Configuración |
|---|---|---|
| Route 53 | DNS Management | Gestión de dominios y políticas de ruteo por latencia. |
| WAF | Firewall de Aplicación | Protección contra inyecciones SQL y ataques XSS en capa 7. |
| ALB | Balanceador de Carga | Enrutamiento basado en rutas (Path-based routing) hacia los servicios de ECS. |
| ECS (Fargate) | Orquestación | Despliegue de microservicios en Go en modo Serverless (sin gestión de servidores EC2). |
| ECR | Registro de Imágenes | Almacenamiento privado de imágenes Docker (Go, Next.js). |
| RDS (PostgreSQL) | Base de Datos | Instancia administrada Multi-AZ con cifrado en reposo y extensión PostGIS. |
| ElastiCache (Redis) | Caché y Sesiones | Gestión de estados de sesión y optimización de consultas de búsqueda. |
| Secrets Manager | Gestión de Secretos | Almacenamiento seguro de credenciales de DB, llaves API y secretos JWT. |
| S3 + CloudFront | Storage y CDN | Almacenamiento de archivos multimedia (fotos perfiles) con entrega global. |
3. Estrategia de Despliegue (CI/CD)
Utilizamos GitHub Actions para automatizar el ciclo de vida del software, garantizando que cada cambio pase por pruebas unitarias en Go antes de llegar a AWS.
- Build & Test: Al realizar un Pull Request a
main, se ejecutan los tests unitarios de Go y el linter de Next.js. - Containerization: Una vez aprobado el PR, se construye la imagen Docker y se envía a Amazon ECR con un tag único (commit SHA).
- Deployment: Se actualiza la "Task Definition" en AWS ECS, ejecutando un Rolling Update para asegurar disponibilidad del 100%.
- Health Checks: El ALB monitorea los nuevos contenedores; si el servicio de Go no responde satisfactoriamente (HTTP 200), se realiza un Rollback automático.
4. Seguridad de Infraestructura (IAM & VPC)
Bajo el Principio de Menor Privilegio (PoLP):
- IAM Task Roles: Cada microservicio tiene un rol de IAM exclusivo. El servicio de
Searchno tiene permisos sobre elSecrets Managerdel servicio deAuth. - Security Groups: El acceso a la base de datos RDS está restringido por puerto (5432) y únicamente se permite tráfico originado desde el clúster de ECS.
- Cifrado: Todos los datos en reposo (EBS, S3, RDS) y en tránsito (TLS 1.3) están cifrados bajo estándares AES-256.
5. Monitoreo y Observabilidad
5.1 CloudWatch Logs & Alarms
- Logs: Centralización de logs estructurados en JSON.
- Alertas: Notificaciones vía SNS si el consumo de CPU/Memoria en Fargate excede el 80% o si el RDS reporta conexiones inusuales.
5.2 AWS X-Ray (Tracing)
- Implementación de tracing para visualizar la comunicación entre Next.js y los microservicios en Go, permitiendo identificar cuellos de botella en tiempo real.
6. Infrastructure as Code (IaC)
Toda la infraestructura descrita debe ser desplegada utilizando Terraform o AWS CDK.
- Repositorio:
/infrastructureen el monorepo. - Aislamiento: Entornos
stagingyproductiontotalmente separados mediante VPCs independientes para evitar colisiones.
7. Convenciones de Código (Go + Clean Architecture)
- Módulos por servicio: repos separados o workspaces; nunca importes código de otro servicio directamente.
- Árbol de carpetas (por microservicio):
/cmd/<service>/main.go(wire DI, config, server bootstrap)/internal/domain/<context>(entidades, interfaces de repositorios y servicios de dominio)/internal/application/<context>(use cases, input/output DTO internos)/internal/infrastructure/persistence(Postgres/Redis adapters),/pubsub,/clients/internal/interfaces/http(handlers, middleware, validaciones, mapping DTO↔usecase)/pkgpara utilidades compartidas cross-context (evitar lógica de dominio aquí)
- Dependencia unidireccional: interfaces definen dependencias; infra implementa; handlers solo orquestan use cases.
- DTOs HTTP vs dominio: request/response de OpenAPI son modelos de interfaz; mapear a/desde modelos de dominio en la capa de application.
- Validaciones: reglas de negocio en use cases; validaciones de forma (email, tamaños) en handlers/DTOs.
- IDs públicos: usar UUIDv4/ULID en dominio y DTOs expuestos; si existe PK interna numérica, mapear a
public_id(UUID) y no exponer la PK interna.
7.1 Convenciones de Nombres por Módulo (DDD/Clean)
| Producto/Módulo | Servicio Go | Paquete dominio | Paquete aplicación (use cases) | Prefijo DTO (interfaces/http) | Ruta de handlers | Topic/Queue (si aplica) |
|---|---|---|---|---|---|---|
| Registro | auth-service | internal/domain/auth | internal/application/auth (RegisterUser, VerifyOtp, ResendOtp) | Auth* | interfaces/http/auth | auth.register |
| Autenticación | auth-service | internal/domain/auth | internal/application/auth (Login, RefreshToken, ForgotPassword, ResetPassword, Logout) | Auth* | interfaces/http/auth | auth.login |
| Catálogos | catalog-service | internal/domain/catalogs | internal/application/catalogs (CreateGeoNode, CreateSpecialty, CreateInsurance) | Catalog* | interfaces/http/admin/catalogs | catalogs.update |
| Buscador | search-service | internal/domain/search | internal/application/search (SearchEntities, SearchDoctors) | Search* | interfaces/http/search | search.query |
| Agenda/Citas | appointments-service | internal/domain/appointments | internal/application/appointments (CreateAppointment, CancelAppointment) | Appointment* | interfaces/http/appointments | appointments.* |
| Disponibilidad | availability-service | internal/domain/availability | internal/application/availability (GetAvailability, UpsertSchedule) | Availability* | interfaces/http/availability | availability.* |
| Notificaciones | notification-service | internal/domain/notifications | internal/application/notifications (SendNotification, UpdatePreferences) | Notification* | interfaces/http/notifications | notif.* |
Nota: Los DTOs siguen el prefijo del módulo y no exponen entidades de persistencia; los handlers mapean DTO ↔ use case; los repos son interfaces en dominio/aplicación.
7. Playbook de Disaster Recovery (DR)
- Detección y declaración: Incident Manager notifica severidad SEV1; se nombra Incident Commander.
- Congelar despliegues: Pausar pipelines en
mainy bloquear releases hasta resolución. - Restore base de datos: Usar RDS PITR a snapshot T‑RPO (≤5m); verificar checksum y migrar recursos dependientes.
- Restaurar caché esencial: Cargar seeds mínimos en Redis si aplica (ej. feature flags).
- Rehidratar imágenes/estáticos: Validar buckets S3/CloudFront; restaurar desde backup si hubo corrupción.
- Warm-up y health-check: Desplegar stack con IaC (Terraform/CDK) apuntando al snapshot restaurado; validar health en ECS/ALB.
- Verificación funcional: Smoke tests: login, búsqueda, Validación Triple, creación de cita.
- Comunicación: Aviso a stakeholders con RTO/RPO alcanzados y alcance del impacto.
- Post-mortem: Registrar causa raíz y acciones preventivas; actualizar runbook y alarmas.
7.1 Objetivos formales de continuidad (SLO de plataforma)
| Componente | RPO objetivo | RTO objetivo | Mecanismo |
|---|---|---|---|
| PostgreSQL (RDS) | <= 5 min | <= 60 min | PITR + snapshots automáticos |
| Redis (cache) | <= 15 min | <= 30 min | Rehidratación desde DB + warmup |
| Objetos S3 (media) | <= 24 h | <= 60 min | Versioning + restore |
| Contrato OpenAPI/docs | <= 24 h | <= 30 min | Git + build reproducible |
7.2 Evidencia mínima y cadencia
- Simulacro de restore en
staging: mensual. - Simulacro DR completo (SEV1): trimestral.
- Evidencia requerida: timestamp inicio/fin, RTO real, data loss real (RPO), issues y acciones.
- Ningun cambio mayor de infraestructura se aprueba sin ultimo simulacro vigente (<90 dias).
8. Acceso a Swagger / OpenAPI
- YAML fuente:
static/openapi.yaml(versión draft). - Ruta local en Docusaurus:
http://localhost:3000/swagger. - Cómo visualizar: abrir
/swagger(página de acceso) y luegoswagger.htmlpara la UI interactiva. - Gobernanza: cualquier cambio de endpoints debe actualizar el YAML vía PR junto con la documentación técnica asociada.
- Accesos estándar:
/swagger(landing),/swagger.html(Swagger UI) y/openapi.yaml(contrato fuente).
9. Migraciones y Datos
- Herramienta sugerida: golang-migrate/tern (o equivalente) versionada en repo (
/database/migrations). - Naming:
YYYYMMDDHHMM_<breve_nombre>.sql. Un archivo up y otro down por cambio. - Orden de aplicación: siempre en secuencia temporal; no saltar versiones. Probar en staging antes de prod.
- Rollback: obligatorio para cambios disruptivos; documentar pasos manuales si no es reversible.
- Seed de datos: mantener seeds mínimas para QA (catálogos base) separadas de migraciones estructurales.
10. Plan de Pruebas
- Unitarias (Go/FE): obligatorio en CI (
go test ./..., unit de front si aplica). - Contract tests: validar OpenAPI (diseño-first) contra handlers; fallar si hay discrepancias.
- E2E felices/borde: flujo registro+login, búsqueda+creación de cita, recordatorios.
- Performance spot-check: p95 endpoints críticos (login, search, availability, appointment create).
11. Compatibilidad y Entornos
- Navegadores: Chrome/Edge/Firefox últimos 2; Safari última mayor; sin IE.
- Breakpoints: mobile ≤768px, tablet 769‑1024px, desktop >1024px.
- Zonas horarias: API en UTC; front convierte a TZ del usuario.
- i18n: mensajes en español por defecto; otros idiomas vía i18n del front (cuando se active).
12. Variables de Entorno y Secrets
- Backend: inyectar vía Vault/Secrets Manager (no en repo). Documentar claves críticas: DB DSN, JWT secret, proveedores email/SMS/push, feature flags.
- Front:
VITE_*publicables; no exponer secretos. Mantener.env.examplecon variables no sensibles.
13. Entorno local dockerizado (backend)
Se define como estándar para desarrollo local un stack de datos en Docker, sin exponer credenciales productivas.
postgres:15+postgispara paridad con producción.redis:7para sesiones/cache.- Volumen persistente local (
./.docker/volumes) para no perder datos de pruebas. - Carga de seed mínima (catálogos base) al levantar el entorno.
docker-compose.yml base sugerido:
services:
db:
image: postgis/postgis:15-3.4
environment:
POSTGRES_DB: salud_dev
POSTGRES_USER: salud
POSTGRES_PASSWORD: salud_local
ports: ["5432:5432"]
volumes:
- ./.docker/volumes/postgres:/var/lib/postgresql/data
redis:
image: redis:7
ports: ["6379:6379"]
volumes:
- ./.docker/volumes/redis:/data
Recomendación: implementar este compose en backend cuando inicie la fase de implementación, junto con migraciones (
make migrate-up) y seed (make seed-dev).