Saltar al contenido
Gontzal Bilbao
← blog

Alertas preventivas en AWS como código con Terraform

Cómo diseño alertas preventivas en AWS como código: pocas alarmas calibradas, naming por entorno, módulo dedicado y rollout dev → staging → prod.

serie · Alertas en AWS como código
Alertas preventivas en AWS como código con Terraform

El problema

Monté un juego mínimo de alertas preventivas para EC2 como código: cuatro alarmas, dos severidades, un topic SNS por entorno y un despliegue por fases. Antes de escribir una línea de Terraform, decidí qué alertar, cómo nombrarlo y en qué orden desplegarlo.

Crear alarmas a mano en la consola está bien para aprender. El problema llega con el segundo entorno: nadie sabe quién cambió un umbral, ni por qué staging y prod ya no coinciden.

Con las alarmas en código, cada cambio pasa por un PR, se lee en el plan y se repite igual en todos los entornos. Este post recoge las decisiones; la implementación está en Alarmas de infraestructura con Terraform.

idea clave

Las decisiones se toman una vez. El Terraform solo las repite en cada entorno.

Tres piezas, cada una con un trabajo

  1. Las métricas nativas de AWS/EC2, que la instancia publica sin instalar nada.
  2. Las alarmas de CloudWatch, que evalúan un umbral y cambian de estado.
  3. Un topic SNS, que reparte el aviso.

CloudWatch evalúa y SNS distribuye. Al separarlas puedo cambiar el canal (email hoy, Slack o Chatbot mañana) sin tocar ninguna alarma.

Qué alertar: pocas alarmas, bien calibradas

Prefiero cuatro alarmas que se atienden a veinte que se ignoran. Este fue el punto de partida:

AlarmaCondiciónSeveridad
CPUUtilizationmedia > 75 % durante 5 minwarning
CPUUtilizationmedia > 85 % durante 10 mincritical
StatusCheckFailed> 0 en 1 mincritical
CPUCreditBalancesaldo bajo, solo en instancias t*warning

Uso dos severidades y ninguna más. Warning significa «míralo hoy»; critical, «actúa ya». Si una alarma no encaja en ninguna de las dos, probablemente no hace falta.

ojo

La severidad la marca la ventana tanto como el umbral. Un pico de un minuto no es crítico; diez minutos sostenidos, sí.

Naming y etiquetas

Todas las alarmas siguen el mismo patrón, que es el que uso en el resto de la serie:

# patrón de nombre de alarma
<env>-<service>-<resource>-<metric>-<severity>

demo-ec2-jumpbox-cpu-warning
demo-ec2-jumpbox-cpu-critical
demo-ec2-web-cpucreditbalance-warning
demo-ec2-web-statuscheckfailed-critical

Con el nombre así, filtrar por entorno o por severidad en CloudWatch es buscar un prefijo o un sufijo. Además, cada alarma lleva las mismas cinco piezas como etiquetas: Environment, Service, Resource, Metric y Severity.

Un topic SNS por entorno

No mezclo avisos de dev, staging y prod en el mismo topic. Cada entorno tiene el suyo, con el patrón <env>-infra-alerts; en mi cuenta de laboratorio es demo-infra-alerts.

Así un aviso de dev no despierta a nadie, y al probar un entorno nuevo sé que lo que llega viene de ese entorno.

InstanceId o AutoScalingGroupName

Es la decisión que cambia la forma del código, así que la tomé antes de escribir la primera alarma.

  • InstanceId para instancias fijas, como un jumpbox. Es granular, pero si la instancia se reemplaza, la alarma se queda mirando un ID que ya no existe.
  • AutoScalingGroupName para lo que vive detrás de un ASG, como el servidor web. Sobrevive a los reemplazos, pero agrega todas las instancias del grupo.

Con la dimensión del ASG, una instancia saturada puede quedar escondida en la media del grupo. Lo acepto para la capa web; para el jumpbox, no.

Dónde vive en Terraform

Las alarmas y el topic van en un módulo propio, modules/monitoring_ec2_alerts. El root solo le pasa lo que no puede saber: el ID de la instancia, el nombre del ASG y el email del aviso.

Así el root sigue siendo un orquestador y el módulo se reutiliza tal cual en cada entorno. El código completo está en Alarmas de infraestructura con Terraform.

Rollout: un entorno cada vez

Cada entorno valida una cosa distinta:

  1. dev: que los recursos, el naming y el topic SNS son los esperados.
  2. staging: que el mismo módulo se repite sin tocar nada.
  3. prod: aplicar una configuración que ya no da sorpresas.

Dentro de cada entorno sigo también un orden. Primero el topic y su suscripción confirmada, después una sola alarma y una prueba controlada, y al final el resto.

Cada paso entra por un PR: terraform validate, terraform plan y apply solo cuando el diff se entiende de un vistazo. La prueba con carga real la cuento en Alarmas de CloudWatch para EC2, probadas con carga real.

ojo

Una alarma desplegada no está validada hasta que su aviso ha llegado de verdad a alguien.

Antes de escribir Terraform

  • Lista mínima de alarmas, con su severidad y su ventana.
  • Patrón de naming y etiquetas cerrado.
  • Un topic SNS por entorno.
  • InstanceId o AutoScalingGroupName, decidido por recurso.
  • Orden de rollout y prueba real prevista en cada entorno.

Lo que aprendí

Decidir entre InstanceId y AutoScalingGroupName antes de la primera alarma me evitó rehacerlas. Y la diferencia entre warning y critical la puse en la ventana de tiempo, no solo en el umbral.

¿Te ha servido?

Si tienes dudas o lo estás montando tú, cuéntamelo.

Escríbeme Compartir en LinkedIn

sigue leyendo

Alarmas de infraestructura con Terraform

Un módulo Terraform con el topic SNS, la suscripción por email y alarmas de CloudWatch para una instancia fija y para un Auto Scaling Group.

24 feb · 3 miniac

Alarmas de CloudWatch para EC2, probadas con carga real

Creo alarmas de CPU y salud para EC2 con CloudWatch y SNS, por consola y CLI, y compruebo con carga real que el aviso llega.

23 feb · 4 minobservabilidad