Saltar a contenido

IRIS API

Descripción

IRIS API es el backend central de la plataforma IRIS de HTG Express. Es una API REST construida con Laravel (PHP) que gestiona la lógica de negocio: transportes, facturación, cotizaciones, gestión de vehículos, comunicaciones con proveedores y clientes, integración con servicios externos (Expeditors, Project44, Altia, TicketBAI) y notificaciones push.

La aplicación está desplegada en Kubernetes (EKS) en AWS, región eu-south-2. La infraestructura sigue un modelo GitOps: los recursos de Kubernetes se definen mediante un chart de Helm, los valores de configuración por entorno viven en un repositorio Git, y ArgoCD se encarga de sincronizar el estado del cluster con lo declarado en Git.

Arquitectura

graph TB
    User([Usuario / Frontend]) -->|HTTPS| ALB[Application Load Balancer]
    ALB --> Nginx[Nginx]

    subgraph Pod["Pod API (EKS)"]
        Nginx -->|FastCGI :9000| PHP[PHP-FPM 8.3]
        Exporter[PHP-FPM Exporter]
        Cleanup[Temp Cleanup]
    end

    PHP --> Aurora[(Aurora MySQL)]
    PHP --> Redis[(ElastiCache Redis)]
    PHP --> S3[(S3 Bucket)]
    PHP --> ExtServices[Servicios externos]

    Redis -->|Encolado| Workers[Workers KEDA]
    Workers --> Aurora
    Workers --> S3
    Workers --> ExtServices

    Scheduler[CronJob Laravel Scheduler] --> Aurora

    style Pod fill:#f5f5f5,stroke:#333

Componentes

La solución combina servicios gestionados de AWS con recursos desplegados dentro de EKS. El ALB expone la aplicación hacia internet, Kubernetes ejecuta los pods de la API y los workers, y los servicios gestionados externos aportan persistencia, colas, almacenamiento, secretos y observabilidad.

Componente Servicio AWS Función
Load Balancer ALB (Application Load Balancer) Punto de entrada HTTPS, terminación TLS
Aplicación EKS (pods Nginx + PHP-FPM) Procesamiento de peticiones HTTP
Workers EKS (pods PHP) con KEDA Procesamiento asíncrono de colas Redis
Base de datos Aurora MySQL / RDS MySQL Persistencia de datos
Caché y colas ElastiCache Redis Caché de aplicación y broker de colas
Almacenamiento S3 Archivos (CMRs, documentos, imágenes)
Secretos Secrets Manager + ESO Gestión segura de credenciales
Logs CloudWatch Logs Centralización de logs
Métricas CloudWatch + Prometheus Métricas de infraestructura y PHP-FPM

Entornos

IRIS API se despliega en cuatro entornos diferenciados. Los entornos de no-producción (dev, dev-features y test) comparten la cuenta AWS 913305982008, lo que permite centralizar los recursos de validación y desarrollo. Producción se ejecuta en una cuenta AWS independiente (200702211100) para aislar cargas críticas, permisos, certificados, secretos y recursos operativos.

Entorno URL Namespace Cuenta AWS GitOps
Producción iris-api.htg-express.com infra-iris-api-pro 200702211100 pro/values.yaml
Test api-test.htg-express.com infra-iris-api-test 913305982008 test/values.yaml
Dev api-dev-li.htg-express.com infra-iris-api-dev 913305982008 dev/values.yaml
Dev Features api-dev-features.htg-express.com infra-iris-api-dev-features 913305982008 dev-features/values.yaml

Repositorios

El despliegue de IRIS API se apoya en tres repositorios con responsabilidades claramente separadas:

Tipo Proyecto Bitbucket Repositorio Responsabilidad
Código IRIS htgexpress/api Código fuente Laravel y Dockerfile
Helm chart IRIS | Helm charts htgexpress/helm-iris-php Plantillas Kubernetes parametrizadas
GitOps IRIS | GitOps htgexpress/infra-iris-api Valores Helm por entorno

Esta separación permite que el equipo de desarrollo evolucione la aplicación sin tocar infraestructura, que el chart pueda reutilizarse con distintos parámetros y que los cambios de configuración por entorno queden auditados en un repo independiente. ArgoCD combina el chart con el values.yaml correspondiente para generar y aplicar los manifiestos Kubernetes.

Estructura del repositorio GitOps

El repositorio GitOps contiene exclusivamente los valores Helm (values.yaml) para cada entorno. No contiene definiciones de Application de ArgoCD ni manifiestos Kubernetes directos; estas viven en un repositorio de configuración de ArgoCD aparte.

infra-iris-api/
├── dev/
│   └── values.yaml
├── dev-features/
│   └── values.yaml
├── test/
│   └── values.yaml
└── pro/
    └── values.yaml

Helm chart

Todos los recursos Kubernetes que componen el despliegue se generan a partir de un único chart de Helm: infra-iris-api, alojado en el repositorio htgexpress/helm-iris-php. El chart es propio (no reutiliza charts comunitarios) y está versionado de forma independiente al código de la aplicación.

CI/CD

El recorrido completo desde un commit hasta producción tiene tres pasos: Bitbucket Pipelines construye la imagen Docker y la sube a ECR, actualiza el image.tag en el repositorio GitOps y, a partir de ahí, ArgoCD se encarga de sincronizar el cluster.

Pipeline (Bitbucket Pipelines)

Existen dos flujos en el pipeline de la aplicación:

Automático (rama develop)

Se ejecuta en cada push a develop y despliega siempre a dev:

  1. Build: construye la imagen Docker usando docker/php/php.api.dockerfile.
  2. Tag: el tag de la imagen es el SHA corto del commit (7 caracteres, ej.: dc6a4cc).
  3. Push: sube la imagen a ECR.
  4. Deploy: actualiza el image.tag en dev/values.yaml del repo GitOps mediante el pipe deploy-helm-values.
graph LR
    Push[Push a develop] --> Build[Build imagen]
    Build --> ECR[Push a ECR]
    ECR --> GitOps[Actualizar dev/values.yaml]
    GitOps --> ArgoCD[ArgoCD sincroniza]

Manual (cualquier entorno)

La promoción a test, dev-features o pro se hace mediante el pipeline manual-deploy, que permite desplegar cualquier referencia Git a cualquier entorno:

Variable Descripción Valores
GIT_REF Commit SHA, tag o rama current (por defecto), SHA, tag, rama
ENVIRONMENT Entorno destino dev, dev-features, test, pro

Pasos:

  1. Resuelve la referencia Git y determina el tag de imagen (tag Git si existe, si no SHA corto).
  2. Verifica si la imagen ya existe en ECR para evitar builds innecesarios.
  3. Si no existe, construye y sube la imagen.
  4. Actualiza el image.tag en {ENVIRONMENT}/values.yaml del repo GitOps.

En la práctica, esto significa que dev recibe un SHA en cada push a develop, mientras que test y pro reciben tags semánticos (1.1.165, 1.1.164...) lanzados manualmente cuando una versión está validada.

Variables de pipeline requeridas

Variable Descripción
AWS_ACCESS_KEY_ID Credenciales IAM para ECR
AWS_SECRET_ACCESS_KEY Credenciales IAM para ECR
AWS_REGION Región del registry ECR
AWS_ACCOUNT_ID ID de cuenta AWS
ECR_REPOSITORY Nombre del repositorio ECR (ej.: iris/api)
BITBUCKET_USERNAME Usuario para clonar el repo GitOps
BITBUCKET_APP_PASSWORD App password para clonar el repo GitOps

Imágenes Docker

El pod de la aplicación se construye a partir de dos imágenes propias publicadas en ECR: una imagen base común (sistema operativo + PHP + extensiones) y una imagen de aplicación que añade el código de IRIS API sobre la base. Esta separación reduce el tiempo de build (la base no cambia con cada commit), garantiza un entorno PHP idéntico entre servicios y simplifica las actualizaciones del runtime.

graph LR
    Debian[php:8.3.30-fpm-bookworm<br/>imagen oficial PHP] --> Base[iris/base/php:8.3.30-fpm<br/>imagen base HTG]
    Base --> App[iris/api:&lt;tag&gt;<br/>imagen de aplicación]
    App --> Pod[Pod en EKS]

Ambas imágenes se almacenan en el mismo registry ECR:

203965864736.dkr.ecr.eu-west-1.amazonaws.com

Imagen base: iris/base/php

Imagen compartida entre IRIS API e IRIS Chat. Parte de la imagen oficial php:8.3.30-fpm-bookworm y añade todo lo necesario para ejecutar las aplicaciones Laravel del proyecto.

Campo Valor
Repositorio ECR iris/base/php
Tag actual 8.3.30-fpm
Imagen origen php:8.3.30-fpm-bookworm (Debian Bookworm)
Dockerfile docker/php/php.base.dockerfile (en el repo de IRIS API)
Usuario por defecto laravel (no-root)
Puerto expuesto 9000 (PHP-FPM)
Timezone Europe/Madrid

Extensiones PHP instaladas:

Tipo Extensiones
Core / docker-php-ext-install bcmath, exif, gd (con freetype/jpeg), gmp, intl, pcntl, pdo_mysql, soap, zip
PECL apcu, imagick, mailparse, redis

Paquetes de sistema relevantes:

  • git, curl, zip, unzip: utilidades básicas para Composer y operaciones de build.
  • libfreetype6-dev, libjpeg-dev, libwebp-dev, libpng-dev, libmagickwand-dev: librerías para procesado de imágenes (GD, Imagick).
  • libgmp-dev, libonig-dev, libpq-dev, libssl-dev, libxml2-dev, libzip-dev, libmcrypt-dev, libmemcached-dev: dependencias de las extensiones PHP.
  • tesseract-ocr con paquetes de idioma (deu, eng, fra, spa): OCR para procesado de documentos (CMRs).

La imagen se reconstruye únicamente cuando es necesario actualizar la versión de PHP, alguna extensión o un paquete de sistema. No forma parte del pipeline automático de la aplicación.

Imagen de aplicación: iris/api

Es la imagen que efectivamente se despliega en cada release. Se construye mediante un Dockerfile multi-etapa que parte de la imagen base:

Campo Valor
Repositorio ECR iris/api
Dockerfile docker/php/php.api.dockerfile
Imagen base iris/base/php:8.3.30-fpm
Convención de tag SHA corto (dev), tag semántico X.Y.Z (test y pro)

Etapas del build:

  1. Etapa Composer: a partir de la imagen composer:2.9.5, copia el código fuente y ejecuta composer install con flags optimizados para producción:
    • --no-dev: omite dependencias de desarrollo.
    • --optimize-autoloader y --apcu-autoloader: genera un autoload optimizado y cacheable en APCu.
    • --ignore-platform-reqs: ignora los requisitos de plataforma del runtime de Composer (el destino real es la imagen base).
  2. Etapa final: a partir de la imagen base iris/base/php, copia el código de la aplicación y los directorios vendor/ y public/ generados en la etapa anterior. El usuario final del contenedor es laravel.

El tag de la imagen se inyecta dinámicamente desde el pipeline de Bitbucket y queda reflejado en el campo image.tag del values.yaml del entorno correspondiente.

Despliegue (GitOps)

ArgoCD

Una vez la imagen está publicada y el values.yaml del entorno actualizado, ArgoCD entra en juego. Cada entorno tiene una Application de ArgoCD que apunta al chart Helm infra-iris-api y al values.yaml correspondiente del repo GitOps.

El flujo completo de un despliegue es:

  1. El pipeline de Bitbucket (o un cambio manual) actualiza el image.tag en el values.yaml del entorno.
  2. ArgoCD detecta el cambio en el repositorio.
  3. ArgoCD renderiza el chart Helm con los nuevos valores.
  4. ArgoCD aplica los cambios al cluster (rolling update).
  5. Tras la sincronización, el Job de migraciones se ejecuta como hook PostSync.

Migraciones

Las migraciones de base de datos se ejecutan automáticamente como un Job de ArgoCD con hook PostSync:

annotations:
  argocd.argoproj.io/hook: PostSync
  argocd.argoproj.io/hook-delete-policy: BeforeHookCreation

Esto garantiza que las migraciones se ejecuten después de que los pods se hayan actualizado a la nueva versión. El Job tiene un timeout de 300 segundos y 3 reintentos.

Configuración

Esta sección describe cómo se inyecta la configuración a los pods. Hay tres mecanismos diferenciados por su naturaleza: ConfigMaps (no sensible), External Secrets (sensible) y los valores del Helm chart que controlan el dimensionado y comportamiento de cada entorno.

Variables de entorno (ConfigMaps)

Las variables no sensibles se inyectan mediante ConfigMaps. El ConfigMap common contiene la configuración de la aplicación Laravel y se genera a partir del bloque configuration.additionalConfigMaps.common del values.yaml.

Secretos

Los secretos se gestionan mediante External Secrets Operator (ESO), que sincroniza valores desde AWS Secrets Manager hacia Secrets nativos de Kubernetes. La autenticación entre ESO y Secrets Manager utiliza IRSA (IAM Role for Service Accounts), eliminando la necesidad de access keys estáticas dentro del cluster.

Entorno Clave en Secrets Manager IAM Role
Dev infraIrisApi/dev/common InfraIrisApiDev
Dev Features infraIrisApi/devFeatures InfraIrisApiDevFeatures
Test infraIrisApi/test InfraIrisApiTest
Pro infraIrisApi/pro InfraIrisApiPro

Los secretos almacenados se agrupan en las siguientes categorías:

Categoría Variables Descripción
Aplicación APP_KEY, SECRET_*_ENCRYPT Clave de cifrado Laravel
Base de datos DB_*, DB_*_GALOPIN, PRICING_DB_* Conexiones MySQL (principal, Galopin, Pricing)
Redis REDIS_*, REDIS_QUEUE_* Caché y colas
S3 AWS_BUCKET, AWS_URL, AWS_DEFAULT_REGION Almacenamiento de archivos
OAuth PASSPORT_PRIVATE_KEY, PASSPORT_PUBLIC_KEY Claves Laravel Passport (Base64)
Mail MAIL_* Configuración SMTP
IMAP IMAP_* Lectura de buzones (operaciones, tracking, Magreb)
Google GOOGLE_* FCM (push notifications), Maps
Pusher PUSHER_* WebSockets
NAS/FTP NAS_FTP_* Acceso a NAS para documentos SUN
TicketBAI CERT_TBAI_*, HTG_*, LICENCIA_TBAI, etc. Facturación electrónica TicketBAI
Telegram TELEGRAM_BOT_TOKEN Notificaciones Telegram

Configuración por entorno

Aunque todos los entornos usan el mismo chart, los values.yaml se diferencian para ajustar el dimensionado y el comportamiento al uso esperado:

Parámetro Dev Dev Features Test Pro
image.tag SHA commit SHA commit Semántico Semántico
resources.requests.cpu 2 1 1 2
resources.requests.memory 2048Mi 512Mi 512Mi 2048Mi
configuration.phpFpm.maxChildren 4 4 4 16
opcache.memory_consumption 128 128 128 256
autoscaling.enabled false false false true
podDisruptionBudget.enabled - - - true
phpFpmExporter.enabled false false false true (sidecar)
Workers 1 (default) 1 (default) 1 (default) 4 tipos con KEDA
MAIL Mailpit (interno) Mailpit (interno) Mailpit (interno) SMTP real
TICKETBAI_ACTIVE false false false true

Recursos altos en dev

El entorno dev está dimensionado al mismo nivel que producción (2 CPU / 2 GiB) porque se utiliza para reproducir condiciones reales de carga durante el desarrollo. dev-features y test mantienen recursos mínimos al usarse para validación funcional.

Recursos Kubernetes

A partir del chart infra-iris-api y del values.yaml de cada entorno, ArgoCD materializa en el cluster un conjunto de recursos organizados en cinco bloques funcionales: el deployment principal de la API, los workers asíncronos, las tareas programadas, la integración con servicios de plataforma (ALB, ESO, ECR) y las políticas de scheduling.

Esta sección describe qué recursos crea el chart y bajo qué condiciones. Los nombres concretos siguen el patrón infra-iris-api-<entorno> y los valores específicos (réplicas, ARNs, endpoints, IAM roles, certificados ACM) viven en el values.yaml del entorno correspondiente en el repositorio GitOps.

Aplicación

El deployment principal agrupa todos los contenedores del pod web. Algunos son siempre activos y otros se incorporan como sidecars en función de los valores del chart:

Contenedor Imagen Activación Función
nginx nginx (versión por entorno) Siempre Servidor HTTP, proxy FastCGI hacia PHP-FPM
app iris/api:<tag> Siempre Aplicación Laravel sobre PHP-FPM 8.3
php-fpm-exporter hipages/php-fpm_exporter phpFpmExporter.enabled Métricas Prometheus de PHP-FPM
temp-cleanup busybox tempCleanup.enabled Sidecar que limpia ficheros temporales antiguos

Recursos asociados:

Recurso Activación Detalle
Service Siempre ClusterIP, puerto 80 (apunta a nginx)
HPA autoscaling.enabled Autoescalado por CPU y métrica PHP-FPM (ver Autoescalado)
PodDisruptionBudget podDisruptionBudget.enabled Evita interrupciones simultáneas durante drenajes o consolidación de nodos

Exposición externa

El acceso desde internet se canaliza a través de un Ingress que el AWS Load Balancer Controller materializa como un Application Load Balancer. La estructura del Ingress es común a todos los entornos; los datos específicos (host público, ARN del certificado, nombre del ALB) se inyectan desde las anotaciones del values.yaml.

Parámetro estructural Valor
IngressClass alb
Esquema internet-facing
Tipo target IP (directo a pods, sin pasar por NodePort)
Política TLS ELBSecurityPolicy-TLS13-1-2-2021-06 (TLS 1.3 / 1.2)
Redirección HTTP→HTTPS Habilitada
Health check path /api/v1/test (/ en no-producción)
Parámetro por entorno Origen
Host público ingress.hosts[].host
Certificado TLS (ACM) Anotación alb.ingress.kubernetes.io/certificate-arn
Nombre del ALB Anotación alb.ingress.kubernetes.io/load-balancer-name

Workers asíncronos

Los workers se despliegan como Deployments independientes (uno por tipo de cola Redis). Cada entrada de workers[] en el values.yaml se traduce en:

  • Un Deployment que ejecuta php artisan queue:work --queue=<cola> ....
  • Opcionalmente un ScaledObject de KEDA que escala el deployment según la longitud de la lista Redis correspondiente (worker.autoscaling.enabled). KEDA crea internamente el HPA asociado.

El número y tipo de workers varía por entorno:

  • No-producción (dev, dev-features, test): un único worker default con réplica fija.
  • Producción: cuatro workers diferenciados por cola (default, priority, multimail, vehicle-position-autovalidation), todos con autoescalado KEDA.

Los rangos de réplicas y umbrales de cada worker se definen en pro/values.yaml.

Tareas programadas y puntuales

Recurso Nombre lógico Descripción
CronJob laravel-scheduler Ejecuta php artisan schedule:run cada minuto (timezone Europe/Madrid)
CronJob run-commands Comandos ad-hoc; suspendido por defecto, se activa manualmente cuando se necesita
Job migrations php artisan migrate --force; se lanza como hook PostSync de ArgoCD en cada despliegue

Estos recursos se definen en los bloques cronjobs[] y jobs[] del values.yaml. Cada entrada con enabled: true se materializa como un manifiesto independiente.

Configuración e identidad

Estos recursos no se ejecutan como pods, pero son necesarios para que el deployment funcione correctamente:

Recurso Nombre lógico Función
ConfigMap common Variables de entorno de la aplicación Laravel
ConfigMap nginx Configuración del servidor nginx
ConfigMap php Directivas de php.ini (timezone, opcache, memory_limit, etc.)
ConfigMap php-fpm Configuración del pool FPM (www.conf, overrides)
SecretStore aws-secretsmanager Conexión de ESO con AWS Secrets Manager (autenticación IRSA)
ExternalSecret common Sincroniza los secretos de la aplicación a un Secret de K8s
ExternalSecret ecr-image-pull-secret Genera el dockerconfigjson necesario para pull de imágenes desde ECR
ServiceAccount infra-iris-api-<env> IRSA para Secrets Manager (rol InfraIrisApi<Env>)
ServiceAccount infra-iris-api-<env>-ecr IRSA para ECR (rol ecr-access-shared-htg-{pro|nonpro})
PodMonitor infra-iris-api-<env> Configura Prometheus para recolectar métricas del php-fpm-exporter (solo si está activo)

Autoescalado

El chart soporta dos mecanismos de autoescalado independientes:

HPA del deployment principal (activado por autoscaling.enabled). Se basa en dos métricas combinadas:

Métrica Origen Configurable en
CPU Uso medio de CPU de los pods autoscaling.targets.cpu
phpFpmProcessUtilization Porcentaje de procesos PHP-FPM activos (php-fpm-exporter + PodMonitor) autoscaling.targets.phpFpmProcessUtilization

Los rangos minReplicas / maxReplicas y los targets concretos se definen en el values.yaml del entorno. En los entornos de no-producción el HPA está deshabilitado y se usa una réplica fija.

KEDA para workers (activado por workers[].autoscaling.enabled). Cada worker tiene su propia configuración de escalado dirigida por eventos de cola Redis, lo que permite que workers de baja prioridad lleguen a una réplica residual mientras que workers críticos arranquen con un mínimo alto para absorber picos. Los parámetros (minReplicaCount, maxReplicaCount, listLength, pollingInterval, cooldownPeriod) se definen por entrada en el values.yaml.

Scheduling

Los pods están configurados para ejecutarse en el NodePool compute de Karpenter, separado del NodePool por defecto del cluster. Esto se logra combinando nodeSelector y tolerations:

nodeSelector:
  node-pool: compute
tolerations:
  - key: karpenter.sh/nodepool
    value: compute
    effect: NoSchedule

El deployment principal aplica además una regla de anti-afinidad preferente para distribuir las réplicas en nodos distintos y mejorar la tolerancia a fallos de nodo:

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app.kubernetes.io/name: infra-iris-api
          topologyKey: kubernetes.io/hostname

Operaciones

Health checks

La aplicación expone health checks en dos niveles, configurados como probes del pod principal:

Probe Puerto Path Descripción
Startup 80 (Nginx) /api/v1/test Espera hasta 60s (30 intentos × 2s) a que la app arranque
Readiness 9000 (PHP-FPM) TCP Verifica que PHP-FPM acepta conexiones
Liveness 9000 (PHP-FPM) TCP Reinicia el pod si PHP-FPM deja de responder

Verificar manualmente desde fuera del cluster:

curl -s https://iris-api.htg-express.com/api/v1/test

Logs

Los logs se centralizan en CloudWatch Logs mediante Fluent Bit (aws-for-fluent-bit, desplegado como DaemonSet en kube-system).

Flujo de logs

Fluent Bit recoge los logs de stdout/stderr de cada contenedor (/var/log/containers/*.log) y aplica un pipeline con dos ramas: una específica para IRIS API y un OUTPUT catch-all para el resto del cluster.

graph LR
    Containers["/var/log/containers/*.log"] --> Tail[Input: tail]
    Tail --> K8sFilter[Filter: kubernetes]
    K8sFilter -->|Pod infra-iris-api*| IrisRewrite[Rewrite tag + JSON parser]
    K8sFilter -->|Resto| CatchAll[(Log group catch-all)]
    IrisRewrite --> IrisOutput[(Log group infra-iris-api)]
  • Pods de la API y el scheduler (infra-iris-api-*, contenedores app y nginx): los logs vienen en formato JSON estructurado desde Laravel. Fluent Bit aplica un parser JSON, eleva el bloque context al nivel raíz y los envía al log group de la aplicación, usando el campo stream del log como nombre del stream CloudWatch.
  • Workers de cola, cronjob run-commands, sidecars (temp-cleanup, php-fpm-exporter) y resto del cluster: caen en el OUTPUT catch-all, sin parser JSON, en un único log group por cluster.

Log groups

Los nombres siguen el patrón /aws/eks/<cluster>/.... En el cluster de producción:

Log group Contenido Streams Retención
/aws/eks/htg-pro/infra-iris-api/infra-iris-api-pro Logs estructurados de la API y el scheduler Uno por área de la aplicación (bill, client, transport, app_login, alarms, auto_bill...) 14 días
/aws/eks/htg-pro/infra-iris-api/default Fallback cuando un pod infra-iris-api* emite logs sin el campo stream default 14 días
/aws/eks/htg-pro/aws-fluentbit-logs Catch-all del cluster: workers, sidecars, demás namespaces Prefijo fluentbit-kube.var.log.containers.* 14 días

Los entornos de no-producción siguen el mismo patrón en su cluster correspondiente.

Variable AWS_CLOUDWATCH_GROUP

El ConfigMap common incluye una variable AWS_CLOUDWATCH_GROUP (/pro/service/iris, /dev/service/iris...). Es herencia de la configuración anterior y no se usa en el flujo actual vía Fluent Bit; queda disponible por si alguna integración necesita escribir directamente con el SDK de AWS.

Queries guardadas en CloudWatch Logs Insights

Existe un conjunto de queries preconfiguradas para acelerar el troubleshooting habitual. Se acceden desde CloudWatch → Logs Insights → Queries → Saved queries. Todas atacan el log group catch-all /aws/eks/htg-pro/aws-fluentbit-logs, ya que los workers son la principal fuente de actividad asíncrona a inspeccionar.

Query Propósito
API pro/default-worker - Actividad Últimos 200 mensajes del worker default
API pro/priority-worker - Actividad Últimos 200 mensajes del worker priority
API pro/multimail-worker - Actividad Últimos 200 mensajes del worker multimail
API pro/vehicle-position-autovalidation-worker - Actividad Últimos 200 mensajes del worker correspondiente
API pro/Errores Workers Logs de default-worker con data.level_name = ERROR
API pro/Errores (FAIL) por worker Mensajes con FAIL en cualquier worker (últimas 100 entradas)
API pro/Errores TLS-SMTP Fallos relacionados con TLS o STARTTLS en envíos SMTP
API pro/Resumen jobs por worker y hora Conteo agregado de jobs DONE/FAIL por worker y franja horaria

Consultas ad-hoc

Para investigaciones puntuales:

# Logs estructurados de la API (con context Laravel)
aws logs tail /aws/eks/htg-pro/infra-iris-api/infra-iris-api-pro \
  --profile htg-pro --region eu-south-2 --follow

# Logs del catch-all filtrando por worker
aws logs tail /aws/eks/htg-pro/aws-fluentbit-logs \
  --profile htg-pro --region eu-south-2 --follow \
  --filter-pattern 'default-worker'

# Logs directos desde kubectl (sin pasar por CloudWatch)
kubectl logs -n infra-iris-api-pro deployment/infra-iris-api-pro -c app --tail=100 -f
kubectl logs -n infra-iris-api-pro deployment/default-worker -c app --tail=100 -f

Referencia técnica

Stack

Capa Tecnología Versión
Runtime PHP-FPM 8.3
Framework Laravel 10
Web server Nginx 1.28
Base de datos Aurora MySQL / RDS MySQL 8.0
Caché y colas ElastiCache Redis -
Almacenamiento Amazon S3 -
Contenedor Docker Multi-stage
Orquestación Kubernetes (EKS) 1.32
CI/CD Bitbucket Pipelines -
GitOps ArgoCD -
Helm chart infra-iris-api 0.4.6
Autoescalado workers KEDA -
Secretos AWS Secrets Manager + ESO -
Métricas PHP-FPM php-fpm_exporter + PodMonitor 2.2
Reloader Stakater Reloader -
Autenticación API Laravel Passport (OAuth 2.0) -