AWS EventBridge でメトリクスとイベントの両ターゲットを対象にした通知フローを構築する

メトリクスに応じた処理とイベントに応じた処理を SNS to Chatbot の通知フローのレールに集約する

ここ数ヶ月 AWS EventBridge を利用した通知フローの改善を通して AWS Observability について、その全体像の理解が深まりました。このエントリでは AWS EventBridge を利用した通知フローについて最近の Input Transformer(w/ Input Path, Input Template) の機能追加も含めてその概要を説明します(抽象的な内容が多くなるので実際に EventBridge の使用経験がないと理解しにくいと思いますがご容赦ください)

結論から言うと CloudWatch Alarm の「生の(加工されない)」通知と、それをイベントとして捕捉して加工した「カスタム」通知の 2 通りをそれぞれの通知チャンネルで管理するのがよいのではないかという設計に辿り着きました。ただ、これはあくまで個人的なベストプラクティスです。EventBridge は AWS の中でも比較的新しいサービスであり 2023年3月に他の AWS サービスからイベントを EventBridge に送信することが可能になり、2023年9月に Input Transformer(w/ Input Path, Input Template) で Chatbot に送る通知内容のカスタマイズが可能になるなど進化を続けているので、現状では AWS 側もベストプラクティスが提供できていない雰囲気を感じています。

上記の図だと 3 段階のインシデントレベル(= sev: severity level) ごとに Slack のチャンネルを用意して以下のように運用するのがよいと考えています(Slack だとチャンネル名は alphabetical にソートされるので最もインシデントレベルが高い 1 が上にくるのもよいと思います)

  • projectX-alerts-raw[123]: メトリクスに応じた CloudWatch Alarm の「生の(加工されない)」通知。人間が読むことを期待していない。
  • projectX-alerts-sev[123]: イベントに応じた CloudWatch Alarm State Change を EventBridge の InputTransformer(w/ Input Path, Input Template) で「カスタム」した通知。人間が読むことを期待している。こちらの通知に「インシデントレベル」「担当チームのメンション」「次にやること」を載せる。

CloudWatch Alarm にはもともと In Alarm/OK 時に通知する SNS topic を指定することができました。ただ、通知内容のフォーマットを変更することはできず、一部のマークダウンに必要な情報を記載するのみが可能です(日本語もこの一部のマークダウンのみ)。

EventBridge も通知内容のフォーマットを変更することはできなかったのですが、2023/09/12 にリリースされた Input Transformer((w/ Input Path, Input Template)で通知内容を変更することができるようになりました(日本語も可能)。この点、通知内容の柔軟性は EventBridge のほうが上かもしれません。 Custom notifications are now available for AWS Chatbot

(余談ですが、ここでの AWS Chatbot は SNS に対する Subscriber であると同時に Slack に対する Publisher になります。Chatbot は EventBridge > SNS と流れてきたメッセージを Slack の chat.postMessage の API 仕様に基づいて HTTP POST してくれるということです)

メトリクスベース(メトリクスに応じたターゲットによる処理) の通知フロー

CloudWatch Alarm を使用する方法で一般的な通知フローです。

metrics from AWS Service > CloudWatch Alarm > SNS > Chatbot > Slack

イベントベース(イベントに応じたターゲットによる処理) の通知フロー

EventBridge を使用する方法で補足するイベントパターンを source や detail-type といった属性で絞り込むことができます。Input Template(w/ Input Path, Input Template) を指定して変数に格納した値を通知に載せることも可能です。

events from AWS Service > EventBridge > SNS > Chatbot > Slack events as CloudWatch Alarm State Change > EventBrdige > SNS > Chatbot > Slack

EventBridge による様々なイベント捕捉パターン

AWS のサービスが発するイベントは Event Structure と呼ばれる共通の json フォーマットの仕様に基づいています。EventBridge で補足するイベントは Source に対象の AWS サービスを指定した後に detail でそれぞれのサービスの持つ固有のパラメータで絞り込むことができます。

例として特定の ElastiCache for Redis のクラスタのイベントを補足するイベントパターンは以下になります。ここで readOnly はイベントが read 系(List, Get, Describe) かそうでないかを表しています。フェイルオーバーなどのイベントは readOnly: false になるのでリソースに何かしらの状態遷移が発生した場合を補足する際に役立ちます。readOnly に似た属性に managementEvent があります。ただもともとデフォルトで read 系のイベントは EventBridge には送られない仕様 となっています。これは AWS Management Console や CLI で状態を確認するための処理、つまり状態遷移が発生しない状態を、わざわざイベントとして処理する必要がないからだと思われます。

{
  "source": ["aws.elasticache"],
  "detail": {
    "eventSource": ["elasticache.amazonaws.com"],
    "requestParameters": {
      "replicationGroupId": ["my-elasticache-dev"]
  },
  "readOnly": [false]
}

これらのイベントは CloudWatch LogGroup をイベントして補足するように設定した後、CloudWatch LogGroup のログを見るのが手っ取り早く確認できます。EventBridge の Input Transformer(w/ Input Path, Input Template) でも CloudWatch LogGroup のログをコピー&ペーストできるようになっているので便利です。なので EventBridge の Rule を作成する場合はまずは Target に SNS Topic ではなく CloudWatch LogGroup を指定して対象の AWS サービスのイベントログの json を吐き出させて、後々の Rule で Input Transformer のフォームに貼り付けるのが有用です。

ひとつ面白いイベントパターンとしては CloudWatch Alarm State Change をイベントして補足できることです(ややこしいのですが「アラームの状態が変化したというイベント」になります)。これを利用すると CloudWatch Alarm が Alarm/OK/Insufficient data といった状態遷移が発生した時にメトリクス経由の通知とイベント経由の通知の 2 種類で通知を飛ばすことが可能になります。2 種類通知が飛ぶのは冗長なので冒頭に挙げた人間が読む用のチャンネル(イベントベース)と生の通知用のチャンネル(メトリクスベース) の 2 つにわけるとよいと思います。

{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"]
}

また CloudTrail の監視もイベントとして処理できるので監査プロセスにも使用できます。

{
   "source" : [ "aws.sts" ],
   "detail-type": ["AWS API Call via CloudTrail"],
   "detail" : {
     "eventName" : ["AssumeRole"]
   }
}

EventBridge の歴史的経緯と CloudWatch からの独立

EventBridge はもともと CloudWatch Events という名称で CloudWatch の機能の一部として提供されていました。今では機能の拡充や他サービスとの繋ぎ込みによって独立したサービスとなり名称も EventBridge となっています。ただ AWS Management Console の CloudWatch 画面からは EventBridge のリンクが残っておりその名残を感じさせます(TV の歴史番組みたいになってきたな)。

時系列 メトリクスレポジトリの名称および説明 イベントレポジトリ名称および説明
CloudWatch: a metrics repository CloudWatch Events: eventbuses
CloudWatch: a metrics repository EventBridge: eventbuses and pipes(receive events and delivers to zero or more targets)

メトリクスとイベントの管理体系を分けた理由はなんでしょうか。個人的には常に発生するメトリクスといつ発生するかわからないイベントの性質の違いからではないかと推察しています。

参考情報

https://pages.awscloud.com/rs/112-TZM-766/images/AWS-21_Observe_and_detect_for_application_availability_and_performance_KMD05-KMD13.pdf docs.aws.amazon.com Custom notifications are now available for AWS Chatbotaws.amazon.com docs.aws.amazon.com