Saltar al contenido principal
Esta guía describe el despliegue completo de la infraestructura EKB EKS en AWS usando Terragrunt. Cubre la instalación de herramientas, configuración del entorno y una secuencia de despliegue por fases diseñada para garantizar el orden correcto de dependencias entre todos los componentes de infraestructura. Los despliegues se organizan en nueve fases:
  1. Gestión de Estado — Inicializa el bucket S3 usado para almacenar el estado de Terraform del entorno.
  2. Infraestructura EKS — Provisiona la VPC, subredes, NAT gateways, roles IAM y el cluster EKS con grupos de nodos administrados.
  3. Almacenamiento y Balanceo de Carga — Despliega el controlador EBS CSI para volúmenes persistentes y el AWS Load Balancer Controller para el ingreso ALB.
  4. Autoescalado con Karpenter — Configura el provisionamiento dinámico de nodos con soporte para instancias Spot y manejo de interrupciones via SQS y EventBridge.
  5. Autoescalado con KEDA — Despliega KEDA para el autoescalado a nivel de pod basado en umbrales de CPU y memoria.
  6. Servicios de Datos — Provisiona Supabase (autoalojado o Cloud), ElastiCache Redis y Amazon MQ RabbitMQ.
  7. Servicios Odin — Despliega el stack de aplicación EKB (Web, FastAPI, Celery, Automator) vía Helm.
  8. Observabilidad con SigNoz — Despliega la traza distribuida, métricas y agregación de logs a través de SigNoz y el agente k8s-infra.
  9. Despliegue Final — Ejecuta un terragrunt apply completo para reconciliar los recursos restantes.
Antes de comenzar, complete la lista de prerrequisitos con el cliente y asegúrese de que todos los placeholders <YOUR_*> en la plantilla del entorno estén completados. Algunos valores, incluyendo el ID de VPC, el endpoint del cluster EKS y los endpoints de Redis y RabbitMQ, solo están disponibles después de fases específicas, por lo que la guía indica exactamente cuándo capturarlos y aplicarlos.

Prerrequisitos

  • AWS CLI configurada con los permisos apropiados
  • Terraform (>= 1.0)
  • Terragrunt (última versión)
  • kubectl para la gestión de Kubernetes
  • helm para la gestión de charts Helm

Guía de Instalación

Instalando Terragrunt

macOS (Homebrew)
Linux (apt)
Windows (Chocolatey)

Instalando kubectl

macOS (Homebrew)
Linux
Windows (Chocolatey)

Instalando Helm

macOS (Homebrew)
Linux
Windows (Chocolatey)

Verificando la Instalación

Configuración de AWS CLI


Creando un Nuevo Entorno

Paso 1: Copie la Plantilla del Entorno

La carpeta env-template-folder contiene archivos pre-estructurados con placeholders <YOUR_*> listos para ser completados. Cópiala completamente para crear su nueva carpeta de entorno.

Paso 2: Verifique que Todos los Placeholders Estén Presentes

Todos los placeholders siguen la convención <YOUR_*>. Los pasos a continuación describen cómo completarlos archivo por archivo.

Paso 3: Provisione Certificados SSL (AWS ACM)

Antes de establecer las variables de entorno necesita los ARNs de los certificados. Use la Consola de AWS para solicitar certificados SSL en AWS Certificate Manager (ACM) para todos los dominios que servirá su entorno. Opción A: Un solo certificado wildcard (recomendado) Un solo certificado wildcard cubre todos los subdominios con un solo ARN. Por ejemplo, si su dominio base es app.example.com, un solo certificado *.app.example.com cubre: Opción B: Certificados por servicio Solicite un certificado por dominio si no puede usar un wildcard. Repita los pasos a continuación para cada dominio: <YOUR_WEB_DOMAIN>, <YOUR_API_DOMAIN>, <YOUR_AUTOMATOR_DOMAIN>, <YOUR_SUPABASE_DOMAIN> (solo si ENABLE_SUPABASE=true), <YOUR_SIGNOZ_DOMAIN> (solo si ENABLE_SIGNOZ=true). Solicitando un certificado en la Consola de AWS
  1. Abra la consola de AWS Certificate Manager
  2. Cambie a la región correcta (arriba a la derecha) — debe coincidir con <YOUR_AWS_REGION>
  3. Haga clic en Solicitar un certificadoSolicitar un certificado públicoSiguiente
  4. Debajo de Nombre de dominio completo, ingrese el wildcard (ej., *.app.example.com) o un dominio específico
  5. Establezca el Método de validación en Validación por DNS
  6. Haga clic en Solicitar — el certificado se crea en estado Pending validation
Agregando el registro CNAME de validación DNS ACM genera un registro CNAME que debe agregar a su proveedor de DNS para demostrar la propiedad del dominio. Obtenga los valores de la Consola de ACM abriendo el certificado y expandiendo el dominio bajo Dominios.
Incluya el punto final (.) al final de los valores CNAME si su proveedor de DNS lo requiere.
Cloudflare
  1. Inicie sesión en Cloudflare → seleccione su dominio → vaya a DNSRecordsAdd record
  2. Establezca el Tipo en CNAME
  3. Pegue el nombre CNAME de ACM en Name y el valor CNAME de ACM en Target
  4. Establezca el Estado del proxy en DNS only (icono de nube gris) — el certificado no se validará a través del proxy de Cloudflare
  5. Haga clic en Save
Route 53
  1. Abra la consola de Route 53 → Hosted zones → seleccione su zona → Create record
  2. Establezca el Tipo de registro en CNAME
  3. Pegue el nombre CNAME de ACM en Record name (solo la parte del subdominio) y el valor en Value
  4. Establezca TTL en 300 y haga clic en Create records
En ACM también puede hacer clic en Create records in Route 53 para que ACM agregue el registro automáticamente si la hosted zone está en la misma cuenta.
Una vez que el DNS se propague (típicamente 1–5 minutos), el estado del certificado cambia a Issued. Copie el ARN desde la parte superior del certificado: se ve como arn:aws:acm:<region>:<account-id>:certificate/<uuid>.

Paso 4: Establezca las Variables de Entorno

Establezca estas variables de entorno del shell antes de ejecutar cualquier comando de Terragrunt. Son leídas directamente por terragrunt.hcl a través de get_env().

Instancias Spot y Cargas de Trabajo con Estado

Las instancias Spot se configuran por NodePool en values/karpenter.yaml, no a través de variables de entorno. Cada NodePool declara su propia estrategia de capacidad: El NodePool application usa familias de instancias m/c (generación 5+) con solo bajo demanda. Los pods del servicio Supabase se fijan aquí mediante nodeSelector: workload-type: "application" para garantizar que nunca sean interrumpidos por un evento de recuperación Spot. El NodePool database-dedicated nunca usa Spot. Usa consolidationPolicy: WhenEmpty para que Karpenter no evict un nodo que aún tiene un pod ejecutándose, lo que lo hace seguro para cargas de trabajo con estado como PostgreSQL y réplicas de CloudNativePG. Pautas para aplicaciones con estado en Spot:
  • No programe bases de datos, colas persistentes o cualquier pod con un PersistentVolumeClaim en NodePools Spot.
  • Use un nodeSelector dirigido a node-type: database-dedicated con la tolerancia database-workload: "true" correspondiente para pods de bases de datos.
  • Use nodeSelector: workload-type: "application" para servicios de usuario sin estado que deben permanecer disponibles sin interrupciones.
  • Para cargas de trabajo de segundo plano (Web, API, Celery, Automator), el NodePool Spot general es apropiado — el manejador de interrupciones SQS de Karpenter drena los nodos Spot graciosamente antes de que AWS los recupere, y el conteo mínimo de réplicas de KEDA (≥ 2) garantiza disponibilidad durante la sustitución de nodos.
  • Para deshabilitar Spot globalmente, elimine "spot" de la lista de valores en cada NodePool dentro de values/karpenter.yaml.
Cómo Karpenter maneja las alertas de interrupción Spot: AWS proporciona un aviso de interrupción de 2 minutos antes de terminar una instancia Spot. Karpenter usa EventBridge y SQS para actuar automáticamente:
Esto se configura en el bloque karpenter en terragrunt.hcl:

Paso 5: Actualice los Valores Específicos del Entorno

Realice una búsqueda y reemplazo en todos los archivos de su nueva carpeta de entorno para los siguientes placeholders:

5.1 terragrunt.hcl — Configuración central del cluster

5.2 state/terragrunt.hcl — Bucket de estado S3

5.3 values/infrastructure.yaml — AWS Load Balancer Controller

Obtenga el ID de la VPC después de que se cree el cluster EKS antes de desplegar el AWS Load Balancer Controller.

5.4 values/karpenter-values.yaml — Controlador Karpenter

Obtenga el endpoint del cluster EKS después de que se cree el cluster EKS y antes de desplegar Karpenter.

5.5 values/karpenter-nodeclasses.yaml — Clases de nodos Karpenter

5.6 values/aws-ebs-csi-driver.yaml — Controlador EBS CSI

5.7 values/karpenter.yaml — Karpenter NodePools

Los nombres de clases de nodo (general, compute-intensive, memory-intensive, gpu, database) deben coincidir con las entradas en karpenter-nodeclasses.yaml.

5.8 values/keda.yaml — KEDA Autoscaler

No se requieren placeholders específicos del entorno. Los límites de recursos y los conteos de réplicas están preconfigurados con valores predeterminados razonables. Revise y ajuste si es necesario.

5.9 values/supabase.yaml — Aplicación Supabase (solo si ENABLE_SUPABASE=true)

Todas las claves a continuación deben generarse de forma consistente y compartirse con ha-supabase-db.yaml. Generarlas una vez y usar los mismos valores en ambos archivos.

5.10 values/ha-supabase-db.yaml — DB HA de Supabase (solo si ENABLE_HA_SUPABASE_DB=true)

Los secretos aquí deben coincidir con supabase.yaml. Use los mismos valores generados para postgresPassword, jwtSecret, anonKey y serviceRoleKey.
La clase de almacenamiento (ebs-csi-gp2), el conteo de instancias y los límites de recursos están preconfigurados. Ajuste postgres.storage.size y postgres.walStorage.size para su volumen de datos esperado.

5.11 values/cloudnative-pg.yaml — Operador CloudNativePG (solo si ENABLE_CNPG=true)

No se requieren placeholders específicos del entorno. Esto despliega solo el controlador del operador CNPG. Los valores predeterminados (3 réplicas, límites de recursos) son adecuados para la mayoría de los entornos.

5.12 values/odin-services.yaml — Servicios de aplicación Odin

Los endpoints de Redis y RabbitMQ solo están disponibles después de que Terraform cree esos recursos de AWS. Los ARNs de certificados deben provisionarse en ACM antes del despliegue.
Configuraciones generales: Supabase (dataServiceConfig) — autoalojado (ENABLE_SUPABASE=true): Supabase (dataServiceConfig) — Supabase Cloud (ENABLE_SUPABASE=false): Redis:
RabbitMQ:
SSL / ARNs de Certificados:
Claves Supabase del frontend web — autoalojado (ENABLE_SUPABASE=true): Claves Supabase del frontend web — Supabase Cloud (ENABLE_SUPABASE=false):

5.13 values/signoz.yaml — Observabilidad SigNoz (solo si ENABLE_SIGNOZ=true)

5.14 values/signoz-k8s-infra.yaml — Métricas K8s de SigNoz (solo si ENABLE_SIGNOZ=true)

El endpoint del colector OTel (signoz-otel-collector.monitoring.svc.cluster.local:4317) está preconfigurado asumiendo que tanto SigNoz como k8s-infra se despliegan en el namespace monitoring. No se necesita cambio a menos que use un nombre de release personalizado.

Recordatorio del Orden de Despliegue

Algunos valores solo están disponibles después de que cierta infraestructura se haya desplegado. Siga este orden:
  1. Antes de cualquier despliegue — Establecer: <YOUR_ENV_NAME>, <YOUR_AWS_REGION>, <YOUR_AWS_ACCOUNT_ID>, <YOUR_ENVIRONMENT>, <YOUR_PROJECT>, <YOUR_VPC_CIDR>, todos los nombres de dominio, todos los ARNs de certificados, todos los valores de Supabase, <YOUR_TOOLKIT_ENCRYPTION_KEY>, usuario/contraseña de RabbitMQ
  2. Después de crear el cluster EKS — Establecer: <YOUR_VPC_ID> (infrastructure.yaml), <YOUR_EKS_CLUSTER_ENDPOINT> (karpenter-values.yaml)
  3. Después de terraform apply para servicios AWS — Establecer: <YOUR_REDIS_HOST>, <YOUR_RABBITMQ_HOST> (odin-services.yaml)

Paso 6: Verifique que No Queden Placeholders

La salida esperada debería estar vacía, o contener solo referencias a recursos a punto de ser creados (VPC, Redis, MQ, EKS). Si quedan placeholders, consulte las subsecciones del Paso 5 anteriormente. Lista de verificación de archivos:

Fase 1: Configuración de Gestión de Estado

Propósito: Creación del bucket S3 para el estado de Terraform. Cada módulo de gestión de estado del entorno crea un bucket S3 con el patrón odin-terraform-state-{environment-name}, configura cifrado, versionado y bloqueo de acceso público, y usa estado local para el módulo de estado en sí (patrón de bootstrap).

Fase 2: Despliegue de Infraestructura EKS

Propósito: Red central (VPC, subredes, NAT gateway), roles y políticas IAM, cluster EKS y grupos de nodos administrados.

2.1 Ejecución de Prueba — Infraestructura EKS

Infraestructura Central
Roles y Políticas IAM
Cluster EKS y Grupos de Nodos

Usando un Registro Docker Personalizado / Privado

Por defecto, las imágenes de EKB se descargan de Docker Hub usando un secreto llamado regcred. Si el cliente aloja imágenes en un registro diferente, siga estos pasos antes de desplegar odin-services. Paso 1 — Crear el imagePullSecret en el namespace destino
Paso 2 — Establecer el nombre del secreto en values/odin-services.yaml
Paso 3 — Actualizar las referencias de imagen
Paso 4 — Verificar el acceso de descarga antes del despliegue completo

2.2 Desplegar Infraestructura EKS

Paso 1: Infraestructura Central
Después de este paso, actualice vpcId en values/infrastructure.yaml antes de desplegar el AWS Load Balancer Controller.
Paso 2: Cluster EKS, Roles y Políticas IAM
Paso 3: Grupos de Nodos y Add-ons
Después de este paso, actualice CLUSTER_ENDPOINT en values/karpenter-values.yaml antes de desplegar Karpenter.
Verificar Conectividad del Cluster EKS

Fase 3: Almacenamiento y Balanceo de Carga

Propósito: Controlador EBS CSI para volúmenes persistentes, AWS Load Balancer Controller ejecutándose en el grupo de nodos administrado.

3.1 Ejecución de Prueba — Almacenamiento y Balanceo de Carga

Controlador EBS CSI
AWS Load Balancer Controller

3.2 Desplegar Almacenamiento y Balanceo de Carga

Paso 1: Controlador EBS CSI
Verificación
Paso 2: AWS Load Balancer Controller
Verificación

Fase 4: Autoescalado con Karpenter

Propósito: Roles IAM para Karpenter, manejo de interrupciones Spot, controlador Karpenter y pools de nodos.

4.1 Ejecución de Prueba — Karpenter

Recursos IAM de Karpenter
Rol de Servicio Vinculado de EC2 Spot (si las instancias Spot están habilitadas)
Interrupción Spot de Karpenter (si está habilitada en terragrunt.hcl)
Charts Helm de Karpenter
Karpenter NodePools y EC2NodeClasses
Puede aparecer un error esperado durante el plan: API did not recognize GroupVersionKind from manifest (CRD may not be installed). Esto es seguro de ignorar — Kubernetes valida los recursos contra la API en vivo durante el plan, antes de que se instalen los CRDs.

4.2 Desplegar Karpenter

Paso 1: Recursos IAM de Karpenter
Verificación
Paso 2: Rol de Servicio Vinculado de EC2 Spot (si las instancias Spot están habilitadas)
El rol de servicio vinculado de EC2 Spot es a nivel de cuenta (solo uno por cuenta de AWS) y debe existir antes de que Karpenter pueda lanzar instancias Spot.
Opción A: Dejar que Terraform lo cree (recomendado para nuevos despliegues)
Opción B: Importar si el rol ya existe
Paso 3: Interrupción Spot de Karpenter (si está habilitada en terragrunt.hcl)
Verificación
Paso 4: Chart Helm de Karpenter
Verificación
Paso 5: Manifestos de Kubernetes de Karpenter
Verificación

Fase 5: Autoescalado con KEDA

Propósito: KEDA para autoescalado a nivel de aplicación.

5.1 Ejecución de Prueba — KEDA

5.2 Desplegar KEDA

Verificación

Fase 6: Servicios de Datos

Propósito: Supabase (base de datos), ElastiCache (Redis), RabbitMQ (cola de mensajes).
Despliegue primero el operador CloudNativePG, luego el clúster HA de Supabase DB, y luego la aplicación Supabase. El clúster de DB debe estar listo antes de que Supabase inicie.

6.1 Ejecución de Prueba — Servicios de Datos

Paso 1: Operador CloudNativePG (si está habilitado)
Paso 2: DB HA de Supabase (si está habilitado)
Paso 3: Aplicación Supabase (si está habilitado)
Paso 4: Servicios AWS — ElastiCache y RabbitMQ (si está habilitado)

6.2 Desplegar Servicios de Datos

Paso 1: Operador CloudNativePG (si está habilitado)
Paso 2: DB HA de Supabase (si está habilitado)
Verificar el pooler PgBouncer y credenciales después del despliegue:
Use el ClusterIP del pooler (o EXTERNAL-IP si es LoadBalancer) como el valor de SUPABASE_POSTGRES_HOST en values/odin-services.yaml y como secret.db.postgresHost en values/supabase.yaml. Paso 3: Aplicación Supabase (si está habilitado) Todos los pods del servicio Supabase se ejecutan exclusivamente en el NodePool application de Karpenter (solo bajo demanda) para prevenir interrupciones Spot.
Paso 4: Servicios AWS — ElastiCache y RabbitMQ (si está habilitado)
Verificación
Antes de desplegar los Servicios Odin, actualice values/odin-services.yaml con el endpoint de Redis, el endpoint de RabbitMQ y todos los ARNs de certificados obtenidos en esta fase.

Fase 7: Servicios Odin

Propósito: Despliegue de la aplicación vía Helm.
Antes de desplegar, reduzca temporalmente las réplicas de fastapiBackend a una sola para la ejecución inicial de migración de base de datos — establezca replicaCount: 1, workers: 1 y keda.minReplicas: 1. Una vez que la migración se complete exitosamente, revierta estos valores a sus valores de producción predeterminados antes de volver a desplegar.

7.1 Ejecución de Prueba — Servicios Odin

7.2 Desplegar Servicios Odin

Verificación

Fase 8: Observabilidad con SigNoz

Propósito: Monitoreo de logs y métricas.

8.1 Ejecución de Prueba — Charts de SigNoz

8.2 Desplegar Charts de SigNoz

Verificación

Fase 9: Despliegue Final

9.1 Despliegue Completo

Este apply final maneja cualquier recurso restante no explícitamente dirigido en fases anteriores.

9.2 Verificar Despliegue


Solución de Problemas

Problemas de bloqueo de estado
Karpenter no funciona
Problemas con el Balanceador de Carga
Problemas con charts Helm

Limpieza


Monitoreo y Registro


Referencia Rápida — Todos los Comandos de Despliegue

Reemplace your-env-name con el nombre real de su entorno en todo momento. Siempre ejecute ejecuciones de prueba (terragrunt plan) primero para validar su configuración antes de aplicar cambios.