Saltar al contenido principal

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

ServicioFunciónDetalle Técnico / Configuración
Route 53DNS ManagementGestión de dominios y políticas de ruteo por latencia.
WAFFirewall de AplicaciónProtección contra inyecciones SQL y ataques XSS en capa 7.
ALBBalanceador de CargaEnrutamiento basado en rutas (Path-based routing) hacia los servicios de ECS.
ECS (Fargate)OrquestaciónDespliegue de microservicios en Go en modo Serverless (sin gestión de servidores EC2).
ECRRegistro de ImágenesAlmacenamiento privado de imágenes Docker (Go, Next.js).
RDS (PostgreSQL)Base de DatosInstancia administrada Multi-AZ con cifrado en reposo y extensión PostGIS.
ElastiCache (Redis)Caché y SesionesGestión de estados de sesión y optimización de consultas de búsqueda.
Secrets ManagerGestión de SecretosAlmacenamiento seguro de credenciales de DB, llaves API y secretos JWT.
S3 + CloudFrontStorage y CDNAlmacenamiento 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.

  1. Build & Test: Al realizar un Pull Request a main, se ejecutan los tests unitarios de Go y el linter de Next.js.
  2. Containerization: Una vez aprobado el PR, se construye la imagen Docker y se envía a Amazon ECR con un tag único (commit SHA).
  3. Deployment: Se actualiza la "Task Definition" en AWS ECS, ejecutando un Rolling Update para asegurar disponibilidad del 100%.
  4. 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 Search no tiene permisos sobre el Secrets Manager del servicio de Auth.
  • 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: /infrastructure en el monorepo.
  • Aislamiento: Entornos staging y production totalmente 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)
    • /pkg para 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óduloServicio GoPaquete dominioPaquete aplicación (use cases)Prefijo DTO (interfaces/http)Ruta de handlersTopic/Queue (si aplica)
Registroauth-serviceinternal/domain/authinternal/application/auth (RegisterUser, VerifyOtp, ResendOtp)Auth*interfaces/http/authauth.register
Autenticaciónauth-serviceinternal/domain/authinternal/application/auth (Login, RefreshToken, ForgotPassword, ResetPassword, Logout)Auth*interfaces/http/authauth.login
Catálogoscatalog-serviceinternal/domain/catalogsinternal/application/catalogs (CreateGeoNode, CreateSpecialty, CreateInsurance)Catalog*interfaces/http/admin/catalogscatalogs.update
Buscadorsearch-serviceinternal/domain/searchinternal/application/search (SearchEntities, SearchDoctors)Search*interfaces/http/searchsearch.query
Agenda/Citasappointments-serviceinternal/domain/appointmentsinternal/application/appointments (CreateAppointment, CancelAppointment)Appointment*interfaces/http/appointmentsappointments.*
Disponibilidadavailability-serviceinternal/domain/availabilityinternal/application/availability (GetAvailability, UpsertSchedule)Availability*interfaces/http/availabilityavailability.*
Notificacionesnotification-serviceinternal/domain/notificationsinternal/application/notifications (SendNotification, UpdatePreferences)Notification*interfaces/http/notificationsnotif.*

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)

  1. Detección y declaración: Incident Manager notifica severidad SEV1; se nombra Incident Commander.
  2. Congelar despliegues: Pausar pipelines en main y bloquear releases hasta resolución.
  3. Restore base de datos: Usar RDS PITR a snapshot T‑RPO (≤5m); verificar checksum y migrar recursos dependientes.
  4. Restaurar caché esencial: Cargar seeds mínimos en Redis si aplica (ej. feature flags).
  5. Rehidratar imágenes/estáticos: Validar buckets S3/CloudFront; restaurar desde backup si hubo corrupción.
  6. Warm-up y health-check: Desplegar stack con IaC (Terraform/CDK) apuntando al snapshot restaurado; validar health en ECS/ALB.
  7. Verificación funcional: Smoke tests: login, búsqueda, Validación Triple, creación de cita.
  8. Comunicación: Aviso a stakeholders con RTO/RPO alcanzados y alcance del impacto.
  9. Post-mortem: Registrar causa raíz y acciones preventivas; actualizar runbook y alarmas.

7.1 Objetivos formales de continuidad (SLO de plataforma)

ComponenteRPO objetivoRTO objetivoMecanismo
PostgreSQL (RDS)<= 5 min<= 60 minPITR + snapshots automáticos
Redis (cache)<= 15 min<= 30 minRehidratación desde DB + warmup
Objetos S3 (media)<= 24 h<= 60 minVersioning + restore
Contrato OpenAPI/docs<= 24 h<= 30 minGit + 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 luego swagger.html para 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.example con 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 + postgis para paridad con producción.
  • redis:7 para 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).