Spis treści
- Dlaczego zwykła droga przez SNS jest kłopotliwa
- Czego potrzebujesz
- Krok 1 — Utwórz kanał, który dzwoni
- Krok 2 — Utwórz połączenie i API destination
- Krok 3 — Utwórz regułę i transformator wejścia
- Krok 4 — Poznaj, jak naprawdę wygląda zdarzenie
- Krok 5 — Zawęź do tego, co zasługuje na telefon
- Krok 6 — Daj powrotom do normy cichsze drzwi
- Przetestuj, zanim zaufasz
- A co z SNS i drogą „e-mail na telefon”?
- Limity, które mają znaczenie podczas incydentu
- Czego ta konfiguracja nie daje
- Rozwiązywanie problemów
- Najczęstsze pytania
- Czy CloudWatch potrafi zadzwonić na numer telefonu natywnie?
- Czy potrzebuję tematu SNS?
- Czy alarm CloudWatch przebije tryb Nie przeszkadzać?
- Dlaczego nie zasubskrybować po prostu adresu webhooka do SNS?
- Czy to kosztuje coś w AWS?
- Czy mogę dzwonić do różnych osób przy różnych alarmach?
- A co z alarmami w kilku regionach lub kontach?
- Podsumowanie
- Powiązane artykuły
Alarm CloudWatch nie może zadzwonić na Twój telefon. Jego jedyne wbudowane akcje to SNS, Auto Scaling, EC2 i Systems Manager, a SNS kończy się mailem, SMS-em albo kolejką, w którą trzeba akurat patrzeć. Poradniki, które faktycznie doprowadzają do dzwoniącego telefonu, stawiają funkcję Lambda i konto Twilio. Możesz pominąć jedno i drugie: pozwól EventBridge odebrać zmianę stanu alarmu, przekształcić ją w mały JSON i wysłać POST-em na kanał telefoniczny Echobell.
Ten przewodnik obejmuje całą drogę — kanał, regułę EventBridge, transformator wejścia, filtry, dzięki którym dzwonek ma znaczenie, oraz powód, dla którego skierowanie SNS prosto na webhook wygląda, jakby miało działać, a w większości przypadków nie działa.
Dlaczego zwykła droga przez SNS jest kłopotliwa
Domyślna rada brzmi: „alarm → temat SNS → subskrybent”. Dla połączenia telefonicznego oznacza to trzy problemy:
- SNS nie ma protokołu głosowego. Typy subskrybentów to e-mail, SMS, push mobilny, SQS, Lambda, Firehose i HTTP(S). SMS łatwo przegapić i blokuje go tryb Nie przeszkadzać; połączenie głosowe wymaga czegoś, co zbudujesz sam.
- Wiadomość HTTPS to napis wewnątrz napisu. SNS dostarcza swoją kopertę z
Content-Type: text/plain, a sam alarm jest dokumentem JSON zserializowanym w poluMessagetej koperty. Odbiorca webhooka, który czyta pola —AlarmName,NewStateValue— znajduje tylko jeden nieprzezroczysty blok. - Koperta jest duża. Przez podpis, adres URL certyfikatu i link do wypisania się koperta dodaje znacznie ponad kilobajt, zanim zacznie się tekst alarmu. Echobell przycina treść powiadomienia do 1500 bajtów, więc szablon „wrzuć całą treść” ucina wiadomość dokładnie tam, gdzie zaczyna się to, co przydatne.
Możesz sprawić, że SNS zadziała, dokładając Lambdę, która rozpakuje wiadomość i prześle ją dalej. Ale CloudWatch już teraz publikuje każdą zmianę stanu alarmu do EventBridge jako czyste zdarzenie JSON — bez konfigurowania żadnej akcji — a EventBridge potrafi je przekształcić i samodzielnie wywołać endpoint HTTPS.
Czego potrzebujesz
- Konta AWS i uprawnień do tworzenia reguł EventBridge, połączeń i API destinations
- Zainstalowanego Echobella (App Store / Google Play)
- Co najmniej jednego istniejącego alarmu CloudWatch
- Dziesięciu minut
Nic po Twojej stronie nie musi przyjmować ruchu przychodzącego. Żądanie wychodzące wysyła EventBridge.
Krok 1 — Utwórz kanał, który dzwoni
W Echobellu utwórz kanał i ustaw typ powiadomienia na Połączenie. Kanał telefoniczny zachowuje się jak połączenie przychodzące, a nie jak push, więc przechodzi przez tryb Skupienia i Nie przeszkadzać w iOS.
Transformator z kroku 3 wysyła płaską treść z polami alarm, state, reason, region i link, więc szablony zostają krótkie:
Tytuł: {{state}}: {{alarm}}
Treść: {{reason}}
W ustawieniach zaawansowanych ustaw szablon linku, żeby dotknięcie powiadomienia otwierało alarm w konsoli:
{{link}}
Skopiuj adres webhooka kanału z widoku szczegółów:
https://hook.echobell.one/t/<channel-token>
Krok 2 — Utwórz połączenie i API destination
EventBridge wywołuje zewnętrzne endpointy HTTPS przez API destination, które wymaga połączenia (connection) przenoszącego uwierzytelnianie. Echobell uwierzytelnia po tajnym tokenie w adresie URL, więc połączenie jest czystą formalnością — ale EventBridge nie utworzy destination bez niego.
- Otwórz EventBridge → Integration → API destinations → Connections → Create connection
- Name:
echobell - Authorization type: API key
- API key name:
x-source, Value:eventbridge - Utwórz je, potem przejdź do API destinations → Create API destination
- Name:
echobell-calling - API destination endpoint: adres kanału Echobell z kroku 1
- HTTP method:
POST - Invocation rate limit:
1na sekundę w zupełności wystarczy i działa jak zawór bezpieczeństwa - Connection:
echobell
Nagłówek z kluczem API jest wysyłany z każdym żądaniem. Możesz go sprawdzać w warunku kanału Echobell, jeśli chcesz mieć drugą bramkę przed tokenem:
header["x-source"] == "eventbridge"
Krok 3 — Utwórz regułę i transformator wejścia
Wejdź w EventBridge → Rules → Create rule w tym samym regionie co alarmy. Reguły są regionalne; alarm z eu-west-1 jest niewidoczny dla reguły w us-east-1.
Użyj domyślnej szyny zdarzeń (event bus) i reguły typu event pattern. Ten wzorzec dopasowuje każdy alarm, który przechodzi w stan ALARM:
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"state": { "value": ["ALARM"] }
}
}
Jako cel wybierz EventBridge API destination i wskaż echobell-calling. Pozwól konsoli utworzyć nową rolę wykonawczą — nadaje ona events:InvokeApiDestination dla tego destination i nic więcej.
Potem rozwiń 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 wysyła wynik jako application/json, dzięki czemu Echobell może czytać {{alarm}} i {{state}} bezpośrednio.
Krok 4 — Poznaj, jak naprawdę wygląda zdarzenie
Input path czyta ze zdarzenia, które publikuje CloudWatch. W skróconej formie wygląda tak:
{
"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" }
}
}
Co warto wiedzieć, zanim zaczniesz edytować szablon:
- Alarm mieszka pod
detail.$.alarmNamenie dopasuje niczego;$.detail.alarmName— tak. state.reasonto tekst generowany automatycznie. Wskazuje punkt danych i próg, czyli dokładnie to, co chcesz usłyszeć o 3 w nocy.- Nazwy alarmów są wstawiane bez zmian. Cudzysłów w nazwie alarmu lub w powodzie zepsułby JSON produkowany przez transformator. Trzymaj się w nazwach alarmów liter, cyfr, myślników i podkreślników — co i tak jest dobrą praktyką — bo inaczej połączenie zakończy się błędem 400.
- Link wymaga zwykłej nazwy. Nazwa ze spacjami lub znakiem
#nie zadziała poprawnie jako głęboki link; wyszukiwarka w konsoli i tak ją znajdzie.
Krok 5 — Zawęź do tego, co zasługuje na telefon
Kanał alarmów, który dzwoni przy każdym ALARM, to najszybszy sposób, by nauczyć się go ignorować. Filtruj w dwóch miejscach.
We wzorcu EventBridge, który działa, zanim cokolwiek zostanie wysłane:
| Cel | Zmiana wzorca |
|---|---|
| Tylko alarmy produkcyjne | "alarmName": [{ "prefix": "prod-" }] wewnątrz detail |
| Pomijaj wszystko oznaczone jako niepilne | Nazwij je warn-… i użyj "alarmName": [{ "anything-but": { "prefix": "warn-" } }] |
| Tylko wybrane alarmy | "alarmName": ["prod-api-5xx", "prod-db-cpu"] |
| Tylko prawdziwe alarmy, nie stany testowe | Zostaw "state": { "value": ["ALARM"] } — zdarzenie INSUFFICIENT_DATA nigdy nie pasuje |
| Tylko jedno konto lub region | Dodaj "account": ["123456789012"] albo "region": ["us-east-1"] na najwyższym poziomie |
W Echobellu użyj warunku kanału dla tego, czego wzorzec nie wyrazi, na przykład okna czasowego:
state == "ALARM" && (hour >= 17 || hour < 9)
Zmienne czasu w Echobellu są w UTC, więc najpierw przelicz ze swojej strefy. Pełną listę zmiennych ma dokumentacja warunków.
Krok 6 — Daj powrotom do normy cichsze drzwi
Druga reguła z "value": ["OK"] może powiedzieć Ci, że problem minął, bez dzwonienia. Utwórz drugi kanał Echobell typu Pilne (Time Sensitive) (albo normalny), drugie API destination wskazujące na niego i użyj ponownie tego samego transformatora wejścia. Szablon tytułu {{state}}: {{alarm}} czyta się już jako „OK: prod-api-5xx”.
| Reguła | Stan | Typ kanału | Zachowanie |
|---|---|---|---|
alarms-to-call | ALARM, prefiks prod- | Połączenie | Dzwoni przez tryb Skupienia |
alarms-warn | ALARM, prefiks warn- | Pilne | Ekran blokady, bez dzwonka |
alarms-recovered | OK | Normalne | Zwykły push |
Przetestuj, zanim zaufasz
Nie czekaj, aż zepsuje się produkcja. Wymuś na alarmie stan, który chcesz sprawdzić:
aws cloudwatch set-alarm-state \
--alarm-name prod-api-5xx \
--state-value ALARM \
--state-reason "Manual test of the Echobell path"
Alarm wraca do swojego prawdziwego stanu przy następnej ewaluacji, ale zdarzenie zmiany stanu jest prawdziwe i przechodzi przez Twoją regułę. Żeby przetestować wyłącznie stronę Echobella, wyzwól kanał bezpośrednio:
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/"}'
Jeśli curl dzwoni, a test alarmu nie, problem leży w regule, transformatorze albo destination — nie w kanale.
A co z SNS i drogą „e-mail na telefon”?
Jeśli temat SNS masz już wszędzie i nie chcesz ruszać EventBridge, istnieją dwie inne drogi:
- SNS → Lambda → webhook. Kilka linijek kodu parsuje
Message, a potem wysyła płaską treść POST-em na ten sam adres Echobell. Działa, ale odtąd utrzymujesz funkcję, rolę i jej logi. - SNS → e-mail → wyzwalacz e-mail Echobella. Zasubskrybuj do tematu adres wyzwalacza e-mail kanału. Alarm przychodzi jako e-mail, a
{{subject}}i{{text}}w szablonach stają się powiadomieniem. To najmniej konfiguracji ze wszystkich, z zastrzeżeniem, że subskrypcje e-mail w SNS wymagają jednorazowego kliknięcia potwierdzenia, a tekst nie jest przekształcany.
Zasubskrybowanie adresu webhooka Echobell bezpośrednio do tematu jako endpointu HTTPS to droga, której należy unikać: żądanie potwierdzenia przyjdzie jako powiadomienie, a każdy kolejny alarm to długa koperta opisana wyżej.
Limity, które mają znaczenie podczas incydentu
- 1 MiB treści. Echobell odrzuca treści wyzwalacza powyżej 1 MiB z kodem HTTP 413. Przekształcony alarm to kilkaset bajtów, więc tutaj tego nie dotkniesz.
- 120 żądań na minutę na token. Powyżej wyzwalacz odpowiada
429zRATE_LIMIT_EXCEEDEDi nagłówkiemRetry-After. Limit destination, 1 na sekundę, trzyma Cię poniżej tego progu, a EventBridge ponawia zdarzenia, których nie udało się dostarczyć. - 1500 bajtów treści powiadomienia. Dłuższy render jest przycinany.
state.reasonto zdanie lub dwa i się mieści.
Czego ta konfiguracja nie daje
- Brak potwierdzenia. Odebranie połączenia nie mówi CloudWatch niczego i nie wycisza pozostałych subskrybentów.
- Brak eskalacji i rotacji. Dzwonimy do wszystkich zapisanych na kanał; nikt nie jest następny w kolejce.
- Brak deduplikacji poza samym alarmem. Alarm, który „miga” i co kilka minut przechodzi
OK → ALARM, będzie dzwonił za każdym razem. Napraw to dłuższymi okresami ewaluacji alboDatapointsToAlarmw samym alarmie. - Brak synchronizacji dwukierunkowej. Usunięcie przyczyny niczego nie czyści na telefonie.
Jeśli to dyskwalifikuje, potrzebujesz pełnej platformy dyżurowej. Jeśli potrzebujesz „zadzwoń, gdy odpali alarm produkcyjny”, to garść ekranów w konsoli.
Rozwiązywanie problemów
Alarm się odpalił, ale nic nie przyszło. Otwórz zakładkę Monitoring reguły: Invocations pokazuje, czy wzorzec pasował, a FailedInvocations — czy dostarczenie się nie udało. Reguły w innym regionie niż alarm nigdy nie pasują.
Reguła pasuje, ale połączenie kończy się błędem 400. Transformator wyprodukował niepoprawny JSON. Poszukaj cudzysłowu lub backslasha w nazwie alarmu albo powodzie.
Powiadomienie jest puste. Szablon czyta pole, którego transformator nie wysłał. Treść jest płaska: {{alarm}}, nie {{detail.alarmName}}.
Dzwoni wielokrotnie przy jednym alarmie. Alarm „miga”. Wydłuż okres ewaluacji albo wymagaj więcej punktów danych; to ustawienie CloudWatch, nie Echobella.
Dzwoni przy alarmie, którego się nie spodziewasz. Sprawdź, czy we wzorcu nie brakuje filtra prefix, i pamiętaj, że alarmy złożone oraz alarmy tworzone przez inne narzędzia (na przykład polityki Auto Scaling) również emitują zmiany stanu.
Najczęstsze pytania
Czy CloudWatch potrafi zadzwonić na numer telefonu natywnie?
Nie. Akcje alarmów CloudWatch to powiadomienia SNS, Auto Scaling, akcje EC2 i Systems Manager. Połączenie głosowe wymaga usługi zewnętrznej: Lambdy dzwoniącej przez dostawcę, platformy dyżurowej albo dzwoniącego webhooka, jak Echobell.
Czy potrzebuję tematu SNS?
Nie. CloudWatch sam emituje zdarzenia zmiany stanu alarmu do EventBridge, niezależnie od tego, czy alarm ma jakieś akcje. Listę akcji alarmu możesz zostawić pustą.
Czy alarm CloudWatch przebije tryb Nie przeszkadzać?
Tylko jeśli dotrze jako alert w formie połączenia. Kanał Echobell typu połączenie zachowuje się jak połączenie przychodzące, które tryb Skupienia i Nie przeszkadzać w iOS przepuszczają. SMS ani zwykły push — nie.
Dlaczego nie zasubskrybować po prostu adresu webhooka do SNS?
SNS wysyła text/plain z alarmem zserializowanym wewnątrz napisu Message, więc szablon nie odczyta poszczególnych pól, a koperta jest na tyle długa, że zostaje przycięta. SNS wysyła też najpierw potwierdzenie subskrypcji, które przyszłoby jako powiadomienie.
Czy to kosztuje coś w AWS?
Zdarzenia zmiany stanu alarmu trafiają na domyślną szynę zdarzeń bez opłat; wywołania API destination są rozliczane za żądanie. Przy wolumenie zdrowego zestawu alarmów to kwota pomijalna, ale sprawdź aktualny cennik EventBridge dla swojego regionu.
Czy mogę dzwonić do różnych osób przy różnych alarmach?
Tak. Utwórz jeden kanał na grupę odbiorców, jedną regułę na kanał i pozwól każdej osobie zapisać się z wybranym typem powiadomienia. Potwierdzeń nie ma, więc dzwonimy do wszystkich, którzy wybrali „połączenie”.
A co z alarmami w kilku regionach lub kontach?
Reguły są per region, więc utwórz regułę w każdym używanym regionie (ta sama definicja API destination jest powtarzana w każdym regionie). Przy kilku kontach wysyłaj zdarzenia na centralną szynę w jednym koncie i tam umieść regułę.
Podsumowanie
Droga składa się z pięciu części: kanału telefonicznego, połączenia i API destination wskazującego na niego, reguły dopasowującej tylko te alarmy, dla których warto kogoś obudzić, transformatora wejścia spłaszczającego zdarzenie oraz wymuszonego testu set-alarm-state, zanim zaczniesz na czymkolwiek polegać. Cała reszta dotyczy utrzymania jej dostatecznie wąskiej, żeby za miesiąc dzwonek wciąż coś znaczył.
Pobierz Echobella na iPhone'a albo weź go z Google Play, a potem uruchom test set-alarm-state.