CloudWatch専用の通知bot、marbotを使ってみた

CloudWatchのslack連携というとLambdaでpostが鉄板ですが、より良くしようとするとLambdaをメンテしていく必要があります。

メッセージを視覚的に良くするならslackの[attachments](https://api.slack.com/docs/message-attachments)などで工夫が必要だし、用途別に通知を分けるとかなると、Lambdaに分岐書いたりとかLambdaをコピペしたりなど。。。

たまたま、marbotというCloudWatchの専用botを見つけ、試しに導入してみたら結構イイ感じだったのでその紹介です。

## marbotについて

公式サイト - [marbot](https://marbot.io/)

CloudWatch専用の通知botで、アラートのslack通知や簡易的なエスカレーションがあります。
今のところは有料プランはなく、費用ゼロで使用できます。

AWSのChatbotコンテストで入賞してたみたいです。
https://aws.amazon.com/jp/blogs/news/congratulations-to-the-winners-of-the-serverless-chatbot-competition/

**marbotの機能**

[marbot](https://marbot.io/)のFeaturesに説明がありますが、ザックリまとめると以下になります。

- Slackへのアラート通知
- アラートのエスカレーション
- アラートの管理（チェック、パス、クローズ）
- Dailyのアラートサマリ

## 導入方法

ここではCloudWatchの設定（SNSのtopicも登録済み）は済んでいるという前提で進めます。

1. [marbot](https://marbot.io/)に`# Add to Slack`があるので、認可してSlackに追加
1. slackのchannelにmarbotを追加
    - 追加するとSNSで設定するEndpointが表示されます
    - 指定したchannelに参加しているメンバーがmarbot通知の対象になり、これについては後述
1. CloudWatchのnotificationで指定しているSNSにsubscriptionを追加
    - HTTPS形式を選び、2.のEndpointを設定
1. slack上で`You completed the SNS topic subscription`となっていれば、SNS連携は完了

マスクしてますが、ここにEndpointが表示されます。

![invite-image](https://qiita-image-store.s3.amazonaws.com/0/20926/b7632085-9b5f-e817-4271-5d8932502697.png)

あとはCloudWatchのイベントが発火すると、marbotから通知がslackへ送信されます。

## marbotのアラート通知

marbotからのアラート通知ですが、基本はchannelメンバーへのダイレクトメッセージです。
ここではアラート発生の流れと、アラートへのアクション、エスカレーションについて説明します。

### アラートへのアクション

marbotからのアラート通知には、`Acknowledge`,`Pass`,`Close`いずれかのアクションが出来るようになっています。 
実際のインシデント想定をした場合、こんな感じでしょう。

- Acknowledge : アラートの認知、障害内容のチェック開始など
- Pass : 誰かにパス
- Close : 終了

### アラート発生のフロー

実際にやってみたところ、以下の流れになりました。

1. アラート発生 🔔
1. channelのオンラインメンバーにmarbotからアラート通知のダイレクトメッセージ
    - オンラインメンバーが複数の場合、誰か一人に通知するっぽい
1. アラートへのアクション
    - `Acknowledge` => marbotがAcknowledgedと認知
    - `Pass` => marbotが次のオンラインメンバーへ通知
    - `Close` => marbotがClosedと認知

marbotのアラート通知はこんな感じになります。

![alert-image](https://qiita-image-store.s3.amazonaws.com/0/20926/9e509785-1e83-89d4-61f1-0fef71f812a9.png)

### エスカレーション

marbotは特定の条件で、エスカレーションとしてchannelへ全体通知します。

- オンラインメンバーが誰もいなかった
- 通知を受けたメンバーがアクションを起こさなかった（５分固定っぽい）
- 全員が`Pass`した

つまり、誰も気づかなかった、誰も行動を起こさなかったらchannelへの全体通知されることになります。

![escalate-image](https://qiita-image-store.s3.amazonaws.com/0/20926/ca0aaf49-89f4-ea2c-8df1-8aa0e746682d.png)

### Dailyのアラートサマリ

marbotは一日のアラートを集計し、日々channelへこんな感じのまとめを投稿してくれます。
（これはテストで適当に発生させたアラート）

![summary-image](https://qiita-image-store.s3.amazonaws.com/0/20926/328f7639-1762-c1e6-972d-5cad53fa3100.png)

## marbotの運用を考えてみる

marbotはslackのchannelをグループ管理としてみなしているようです。
なので、アラートを受けるべきメンバーを集めたchannelにmarbotを入れれば、アラートのコントロールもしやすくなるかと思います。

例えばこんな感じにわけてみるとか。

- myservice : サービス関係者全員
- myservice-dev : サービスのエンジニアAll
- myservice-incident : 通知に必ず対応すべき関係者
  - marbot参加

ちなみにインテグレーション数ですが、channel個別にmarbotを招待できるので登録は１つで済みます。

## Architectureについて

この記事に、アーキテクチャの概要が説明されていました。
https://cloudonaut.io/marbot-aws-serverless-chatbot-competition/

- AWS Lambda and Amazon API Gateway
- Amazon DynamoDB
- Amazon Kinesis Streams and Amazon Kinesis Analytics
- Amazon SQS
- Amazon SNS and AWS CloudWatch

LambdaとAPI Gateway、DynamoDBはサーバレスの鉄板なので、すぐに想像できましたが、目を引いたのはSQSとKinesisです。

記事を読んで理解できましたが、アラート通知でn分スルーされたらchannelへ通知などを実装するために、SQSをタイマーとして使っているようです。なるほど。

KinesisはDailyサマリーの算出用途ですね。

## まとめ

CloudWatchの通知をSlackに連携していない、またはslackに連携しているけどアラートを放置しがちなケースでは、marbotのエスカレーションが効果的になるかも。