Índice
- Por qué la ruta habitual con SNS se complica
- Qué necesitas
- Paso 1 — Crea un canal que suene
- Paso 2 — Crea la conexión y la API destination
- Paso 3 — Crea la regla y el transformador de entrada
- Paso 4 — Conoce el aspecto real del evento
- Paso 5 — Filtra hasta lo que merece una llamada
- Paso 6 — Dale a las recuperaciones una puerta más silenciosa
- Pruébalo antes de fiarte
- ¿Y SNS y el correo a llamada?
- Límites que importan durante un incidente
- Lo que este montaje no te da
- Resolución de problemas
- Preguntas frecuentes
- ¿Puede CloudWatch llamar a un número de teléfono de forma nativa?
- ¿Necesito un tema de SNS?
- ¿Una alarma de CloudWatch atraviesa No molestar?
- ¿Por qué no suscribir directamente la URL del webhook a SNS?
- ¿Esto cuesta algo en AWS?
- ¿Puedo llamar a personas distintas según la alarma?
- ¿Y las alarmas en varias regiones o cuentas?
- Cierre
- Artículos relacionados
Una alarma de CloudWatch no puede llamar a tu teléfono. Sus únicas acciones integradas son SNS, Auto Scaling, EC2 y Systems Manager, y SNS termina en un correo, un SMS o una cola que tienes que estar vigilando. Los tutoriales que sí consiguen que suene el teléfono montan una función Lambda y una cuenta de Twilio. Puedes prescindir de ambas: deja que EventBridge reciba el cambio de estado de la alarma, lo convierta en un pequeño cuerpo JSON y lo envíe por POST a un canal de llamada de Echobell.
Esta guía cubre todo el camino: el canal, la regla de EventBridge, el transformador de entrada, los filtros que hacen que la llamada siga siendo significativa, y por qué apuntar SNS directamente al webhook parece que debería funcionar y casi nunca lo hace.
Por qué la ruta habitual con SNS se complica
El consejo por defecto es "alarma → tema de SNS → suscriptor". Para una llamada de teléfono eso tiene tres problemas:
- SNS no tiene protocolo de voz. Los tipos de suscriptor son correo, SMS, push móvil, SQS, Lambda, Firehose y HTTP(S). El SMS es fácil de pasar por alto y lo bloquea No molestar; una llamada de voz requiere algo que construyas tú.
- El mensaje HTTPS es una cadena dentro de otra cadena. SNS entrega su sobre con
Content-Type: text/plain, y la alarma es un documento JSON serializado dentro del campoMessagedel sobre. Un receptor de webhook que lea campos —AlarmName,NewStateValue— solo encuentra un blob opaco. - El sobre es grande. Entre la firma, la URL del certificado de firma y el enlace para darse de baja, el sobre añade bastante más de un kilobyte antes de que empiece el texto de tu alarma. Echobell trunca el cuerpo de una notificación a 1500 bytes, así que una plantilla de "volcar todo el cuerpo" se corta justo donde empieza la parte útil.
Puedes hacer que SNS funcione con una Lambda que desenvuelva el mensaje y lo reenvíe. Pero CloudWatch ya publica cada cambio de estado de alarma en EventBridge como un evento JSON limpio —sin ninguna acción que configurar—, y EventBridge puede remodelarlo y llamar él mismo a un endpoint HTTPS.
Qué necesitas
- Una cuenta de AWS y permiso para crear reglas, conexiones y API destinations de EventBridge
- Echobell instalado (App Store / Google Play)
- Al menos una alarma de CloudWatch existente
- Diez minutos
Nada de tu lado tiene que aceptar tráfico entrante. EventBridge hace la petición saliente.
Paso 1 — Crea un canal que suene
En Echobell, crea un canal y pon su tipo de notificación en Llamada. Un canal de llamada se comporta como una llamada entrante en lugar de como un push, así que atraviesa el modo Concentración de iOS y No molestar.
El transformador del paso 3 envía un cuerpo plano con los campos alarm, state, reason, region y link, así que las plantillas se quedan cortas:
Título: {{state}}: {{alarm}}
Cuerpo: {{reason}}
Configura la plantilla de enlace en los ajustes avanzados para que tocar la notificación abra la alarma en la consola:
{{link}}
Copia la URL del webhook del canal desde la vista de detalle:
https://hook.echobell.one/t/<channel-token>
Paso 2 — Crea la conexión y la API destination
EventBridge llama a endpoints HTTPS externos mediante una API destination, que necesita una conexión que lleve la autenticación. Echobell se autentica con el token secreto de la URL, así que la conexión es una formalidad, pero EventBridge no crea un destino sin ella.
- Abre EventBridge → Integration → API destinations → Connections → Create connection
- Name:
echobell - Authorization type: API key
- API key name:
x-source, Value:eventbridge - Créala y ve a API destinations → Create API destination
- Name:
echobell-calling - API destination endpoint: la URL de tu canal de Echobell del paso 1
- HTTP method:
POST - Invocation rate limit:
1por segundo es más que suficiente y actúa como válvula de seguridad - Connection:
echobell
La cabecera de la API key se envía en cada petición. Puedes comprobarla en una condición de canal de Echobell si quieres una segunda barrera delante del token:
header["x-source"] == "eventbridge"
Paso 3 — Crea la regla y el transformador de entrada
Ve a EventBridge → Rules → Create rule en la misma región que tus alarmas. Las reglas son regionales; una alarma en eu-west-1 es invisible para una regla en us-east-1.
Usa el bus de eventos default y una regla de tipo event pattern. Este patrón coincide con toda alarma que pasa a ALARM:
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"state": { "value": ["ALARM"] }
}
}
Como destino, elige EventBridge API destination y selecciona echobell-calling. Deja que la consola cree un nuevo rol de ejecución: concede events:InvokeApiDestination para este destino y nada más.
Después expande Additional settings → Configure target input → Input transformer:
Input path
{
"alarm": "$.detail.alarmName",
"state": "$.detail.state.value",
"reason": "$.detail.state.reason",
"region": "$.region",
"time": "$.time"
}
Template
{
"alarm": "<alarm>",
"state": "<state>",
"reason": "<reason>",
"region": "<region>",
"time": "<time>",
"link": "https://console.aws.amazon.com/cloudwatch/home?region=<region>#alarmsV2:alarm/<alarm>"
}
EventBridge envía el resultado como application/json, que es lo que permite a Echobell leer {{alarm}} y {{state}} directamente.
Paso 4 — Conoce el aspecto real del evento
El input path lee del evento que publica CloudWatch. Recortado, es así:
{
"version": "0",
"id": "c4c1c1c9-6542-e61b-6ef0-8c4d36933a92",
"detail-type": "CloudWatch Alarm State Change",
"source": "aws.cloudwatch",
"account": "123456789012",
"time": "2026-10-16T03:12:44Z",
"region": "us-east-1",
"resources": ["arn:aws:cloudwatch:us-east-1:123456789012:alarm:prod-api-5xx"],
"detail": {
"alarmName": "prod-api-5xx",
"state": {
"value": "ALARM",
"reason": "Threshold Crossed: 1 out of the last 1 datapoints [42.0] was greater than the threshold (10.0).",
"timestamp": "2026-10-16T03:12:44.000+0000"
},
"previousState": { "value": "OK" },
"configuration": { "description": "API 5xx errors on the prod load balancer" }
}
}
Cosas que conviene saber antes de editar una plantilla:
- La alarma vive bajo
detail.$.alarmNameno coincide con nada;$.detail.alarmNamesí. state.reasones texto generado. Nombra el punto de datos y el umbral, que es justo lo que quieres oír a las 3 de la mañana.- Los nombres de alarma se insertan en crudo. Una comilla doble dentro de un nombre de alarma o de un motivo rompería el JSON que produce el transformador. Quédate con letras, dígitos, guiones y guiones bajos en los nombres de alarma —que de todos modos es buena práctica— o la llamada fallará con un 400.
- El enlace necesita un nombre simple. Un nombre con espacios o
#no enlazará correctamente; la búsqueda de la consola lo sigue encontrando.
Paso 5 — Filtra hasta lo que merece una llamada
Un canal de alarmas que suena con cada ALARM es la forma más rápida de enseñarte a ignorarlo. Filtra en dos sitios.
En el patrón de EventBridge, que se evalúa antes de enviar nada:
| Objetivo | Cambio en el patrón |
|---|---|
| Solo alarmas de producción | "alarmName": [{ "prefix": "prod-" }] dentro de detail |
| Omitir lo que no es urgente | Nómbralas warn-… y usa "alarmName": [{ "anything-but": { "prefix": "warn-" } }] |
| Solo alarmas concretas | "alarmName": ["prod-api-5xx", "prod-db-cpu"] |
| Solo alarmas reales, no estados de prueba | Mantén "state": { "value": ["ALARM"] } — un evento INSUFFICIENT_DATA nunca coincide |
| Solo una cuenta o región | Añade "account": ["123456789012"] o "region": ["us-east-1"] en el nivel superior |
En Echobell, usa una condición de canal para lo que el patrón no puede expresar, como una ventana horaria:
state == "ALARM" && (hour >= 17 || hour < 9)
Las variables de tiempo de Echobell están en UTC, así que convierte desde tu zona horaria primero. La referencia de condiciones lista todas las variables.
Paso 6 — Dale a las recuperaciones una puerta más silenciosa
Una segunda regla con "value": ["OK"] puede avisarte de que el problema se ha resuelto, sin sonar. Crea un segundo canal de Echobell de tipo Urgente (Time Sensitive) (o normal), una segunda API destination que apunte a él y reutiliza el mismo transformador de entrada. La plantilla de título {{state}}: {{alarm}} ya se lee como "OK: prod-api-5xx".
| Regla | Estado | Tipo de canal | Comportamiento |
|---|---|---|---|
alarms-to-call | ALARM, prefijo prod- | Llamada | Suena atravesando Concentración |
alarms-warn | ALARM, prefijo warn- | Urgente | Pantalla bloqueada, sin sonar |
alarms-recovered | OK | Normal | Push corriente |
Pruébalo antes de fiarte
No esperes a que se rompa producción. Fuerza una alarma al estado que quieras:
aws cloudwatch set-alarm-state \
--alarm-name prod-api-5xx \
--state-value ALARM \
--state-reason "Manual test of the Echobell path"
La alarma vuelve a su estado real en su siguiente evaluación, pero el evento de cambio de estado es real y pasa por tu regla. Para probar solo el lado de Echobell, dispara el canal directamente:
curl -X POST https://hook.echobell.one/t/<channel-token> \
-H 'Content-Type: application/json' \
-d '{"alarm":"prod-api-5xx","state":"ALARM","reason":"Manual test","region":"us-east-1","link":"https://console.aws.amazon.com/cloudwatch/"}'
Si el curl suena y la prueba de la alarma no, el problema está en la regla, el transformador o el destino, no en el canal.
¿Y SNS y el correo a llamada?
Si ya tienes un tema de SNS por todas partes y no quieres tocar EventBridge, existen otras dos rutas:
- SNS → Lambda → webhook. Unas pocas líneas de código analizan
Messagey luego envían por POST un cuerpo plano a la misma URL de Echobell. Funciona, pero ahora eres responsable de una función, un rol y sus logs. - SNS → correo → disparador por correo de Echobell. Suscribe la dirección del disparador por correo del canal al tema. La alarma llega como un correo, y
{{subject}}y{{text}}en tus plantillas se convierten en la notificación. Es la que menos configuración requiere, con la salvedad de que las suscripciones de correo de SNS necesitan un clic de confirmación única y el texto no se remodela.
Suscribir directamente la URL del webhook de Echobell al tema como endpoint HTTPS es la ruta que conviene evitar: la petición de confirmación llega como notificación, y cada alarma posterior es el sobre largo descrito arriba.
Límites que importan durante un incidente
- 1 MiB de cuerpo. Echobell rechaza con HTTP 413 los cuerpos de disparador de más de 1 MiB. Una alarma transformada ocupa unos cientos de bytes, así que aquí no te lo vas a encontrar.
- 120 peticiones por minuto y token. Por encima, el disparador responde
429conRATE_LIMIT_EXCEEDEDy unRetry-After. El límite de 1 por segundo del destino te mantiene por debajo, y EventBridge reintenta los eventos que no pudo entregar. - 1500 bytes de cuerpo de notificación. Los renders más largos se truncan.
state.reasones una frase o dos y cabe.
Lo que este montaje no te da
- Sin confirmación. Responder la llamada no le dice nada a CloudWatch y no silencia a otros suscriptores.
- Sin escalado ni rotación. Se llama a todos los suscritos al canal; a nadie después.
- Sin deduplicación más allá de la alarma. Una alarma intermitente que pasa de
OK → ALARMcada pocos minutos sonará cada vez. Arréglalo con periodos de evaluación más largos oDatapointsToAlarmen la propia alarma. - Sin sincronización bidireccional. Arreglar la causa no borra nada en tu teléfono.
Si eso es inaceptable, lo que necesitas es una plataforma de guardia completa. Si lo que necesitas es "llámame cuando salte la alarma de producción", esto son un puñado de pantallas de la consola.
Resolución de problemas
La alarma saltó pero no llegó nada. Abre la pestaña Monitoring de la regla: Invocations muestra si el patrón coincidió, FailedInvocations si falló la entrega. Las reglas en una región distinta a la de la alarma nunca coinciden.
La regla coincide pero la llamada falla con un 400. El transformador produjo JSON inválido. Busca una comilla o una barra invertida en el nombre o el motivo de la alarma.
La notificación está en blanco. La plantilla lee un campo que el transformador no envió. El cuerpo es plano: {{alarm}}, no {{detail.alarmName}}.
Suena repetidamente por una misma alarma. La alarma es intermitente. Alarga el periodo de evaluación o exige más puntos de datos; es un ajuste de CloudWatch, no de Echobell.
Suena por una alarma que no esperabas. Revisa si falta un filtro prefix en el patrón, y recuerda que las alarmas compuestas y las creadas por otras herramientas (las políticas de Auto Scaling, por ejemplo) también emiten cambios de estado.
Preguntas frecuentes
¿Puede CloudWatch llamar a un número de teléfono de forma nativa?
No. Las acciones de alarma de CloudWatch son notificaciones de SNS, Auto Scaling, acciones de EC2 y Systems Manager. Una llamada de voz necesita un servicio externo: una Lambda que marque a través de un proveedor, una plataforma de guardia o un webhook de llamada como Echobell.
¿Necesito un tema de SNS?
No. CloudWatch emite eventos de cambio de estado de alarma a EventBridge por sí mismo, tenga o no la alarma acciones. Puedes dejar vacía la lista de acciones de la alarma.
¿Una alarma de CloudWatch atraviesa No molestar?
Solo si llega como alerta tipo llamada. Un canal de Echobell de tipo llamada se comporta como una llamada entrante, que el modo Concentración y No molestar de iOS dejan pasar. Un SMS o un push normal, no.
¿Por qué no suscribir directamente la URL del webhook a SNS?
SNS envía text/plain con la alarma serializada dentro de una cadena Message, así que la plantilla no puede leer campos individuales, y el sobre es lo bastante largo como para truncarse. Además, SNS envía primero una confirmación de suscripción, que llegaría como notificación.
¿Esto cuesta algo en AWS?
Los eventos de cambio de estado de alarma llegan al bus de eventos default sin cargo; las invocaciones de API destination se facturan por petición. Con el volumen de un conjunto de alarmas sano es una cantidad insignificante, pero consulta los precios actuales de EventBridge para tu región.
¿Puedo llamar a personas distintas según la alarma?
Sí. Crea un canal por audiencia, una regla por canal y deja que cada persona se suscriba con el tipo de notificación que prefiera. No hay confirmación, así que se llama a todos los suscritos con "llamada".
¿Y las alarmas en varias regiones o cuentas?
Las reglas son por región, así que crea la regla en cada región que uses (la misma definición de API destination se repite por región). Para varias cuentas, envía los eventos a un bus central en una cuenta y pon la regla allí.
Cierre
El camino son cinco piezas: un canal de llamada, una conexión y una API destination que apunten a él, una regla que coincida solo con las alarmas por las que merece despertar a alguien, un transformador de entrada que aplane el evento y una prueba forzada con set-alarm-state antes de fiarte de nada. Todo lo demás aquí trata de mantenerlo lo bastante estrecho como para que dentro de un mes una llamada siga significando algo.
Descarga Echobell para iPhone o consíguelo en Google Play, y luego lanza la prueba con set-alarm-state.