CloudWatchアラームをSlackへ通知する

EC2運用時に突然空き容量がなくなってサービス停止するといった事態を防ぐためにEC2の空き容量を監視して閾値を下回った場合にSlackへ通知するという機構を実装してみました。

参考にした公式資料はこちらです。
チュートリアル：Slackを使ってみる※英字ドキュメントのみですがChromeで日本語訳したら普通に読めます。
https://docs.aws.amazon.com/ja_jp/chatbot/latest/adminguide/slack-setup.html
Amazon SNS 通知の設定
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/US_SetupSNS.html
# 今回の構成図はこちら
CloudWatchAlarmで閾値超過を検知してSNSで拾い、Chatbot経由でSlackに通知するという流れです。この構成の良いところはサクッと作れるところです。悪いところは通知が全部英語でUTCになるところです。とはいえ、JSTはSlackへの通知時刻で確認できるしアラートに気付いて「むむむ」となってAWSコンソールを覗きにいってもUTC表記なので、通知だけJSTでもメリットはないかもです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/06feb26e-4a74-a4d6-0684-438a9e520135.png" width="500">
なお、作業する順序は、SNS⇒Chatbot⇒CloudWatchAlarmの順がやりやすいと思います。今回の作業もこの順序となります。
# SNSトピックを作成する
CloudWatchAlarmとChatbotの登録の際にSNSトピックが必要になるため、先にSNSトピックを作成しておきます。
Amazon SNSのメニューからトピックを選択して「トピックの作成」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/e37e37e9-a811-2374-a886-e9414a866ddb.png" width="800">
ChatbotのSlack通知ではFIFOタイプのトピックを設定できないため、タイプはスタンダードを選択します。
続いて、名前と表示名を入力してトピックの作成をクリックして作成します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/dd4c718a-6b80-429b-cee9-cae0e44d2c82.png" width="700">
# SlackにAWSアプリを追加して通知用チャネルを作成する
SlackへのAWSアプリの追加は、他のアプリと同じ方法です。
今回は通知用の専門チャネルを作成します。通知用チャネルを作成したらAWSアプリを追加しておきます。
# ChatbotにSlackを追加する
Slackを立ち上げておきます。
AWSコンソールからAWS Chatbotを選択して「チャットクライアントを設定」でSalckを選択した後に「クライアントを設定」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/d226b047-20aa-9529-4760-7596920d19da.png" width="700">
ChatbotからSlackワークスペースへの接続権限を求める画面が表示されるので許可します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/37f5b0d8-c286-dd13-c1b2-448b0258b4c7.png" width="400">
AWSコンソールにSlackワークスペースが追加されます。
「新しいチャネルを設定」で通知先のチャネルを設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/87d93233-7d04-d75d-173d-fc57b955437a.png" width="800">
設定名を入力ししたら、Slackチャネルを入力します。今回はプライベートチャネルに通知するので、そちらを選択します。
チャネルIDはSlackの対象チャネルの「チャネル詳細を取得する」ポップアップの一番下に記載されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/0a761200-b439-f80d-a9ba-d60c141cd3fc.png" width="600">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/300ee38e-4fdf-6d80-a0f1-e2bfe854a277.png" width="500">
アクセス許可では、今回はSlackへ通知するだけなので最小限のアクセス許可にします。
チャネルロールを選択して「テンプレートを使用してIAMロールを作成する」を選びます。ロール名もAWSChatbot-roleのままにします。
ポリシーテンプレートは「通知のアクセス許可」のみを選択します。
チャネルガードレールポリシーでは「CloudWatchReadOnlyAccess」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/bb56d23c-04d1-4c30-a2a1-8fa63234c8ee.png" width="600">
通知では先ほど作成したSNSトピックを選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/8ad583c3-1068-71e9-f3b8-ce93e24b3df9.png" width="600">
なお、この作業で対象のSNSトピックにChatbot用のサブスクリプションが作成されます。SNSトピックを確認すると追加されているのが分かります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/dad70883-0bbc-716a-2fd4-92c7a8668eaf.png" width="900">
# CloudWatchアラームの作成
AWSコンソールからCloudWatchを選択してメニューからアラーム状態を選択します。「アラームの作成」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/27a6cbb2-71c3-b06f-9d5a-96d312eda113.png" width="900">
メトリクスの選択から監視対象のEC2のメトリクスを選択します。なお、1つのアラームに登録できるのは1のメトリクスのみです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/66c99449-4d8a-2045-3a9c-307177d6cb70.png" width="700">
今回はメトリクスの設定は期間以外デフォルトのままにします。今回の期間は15分に設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/74a54d0d-63ce-afd4-7802-ca21d9befd4a.png" width="500">
条件のしきい値は静的を選択し20以下に設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/87a7791d-c0e2-157f-eae4-43d948626fda.png" width="500">
通知ではアラーム状態を選択、既存のSNSトピックを選択を選び通知の送信先でSNSトピックを選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/39c144a6-991f-ceb1-078c-48e98fa51d7a.png" width="500">
続けて、「通知の追加」からOKとデータ不足の通知を追加します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/779e953a-9746-ffb4-a4d6-7656aa1ef7fd.png" width="500">
次ページで設定内容を確認したら「アラームの作成」のクリックでアラームを作成します。
# テストメッセージの送信
ここまで設定が終わったら、送信テストをします。
Chatbotの設定済チャネルを選択して詳細画面を表示して「テストメッセージを送信」をクリックします。無事成功するとSlackの対象チャネルにAWSからメッセージが届きます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/ea44294f-38f7-f554-2c96-9b8eb56ab5f2.png" width="400">
なお、実際のアラートメッセージはこんな感じです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/4ebb73d9-c362-2038-3be0-a3a2e14012af.png" width="500">
なお「続きを見る」のクリックでメトリクスのグラフが表示されます。
# おわりに
作業自体は、はまるポイントもなくサクサク作成することができました。
強いていうなら、多数のCloudWatchAlarmを1対1でSNSトピックに紐づけるかn対1で紐づけるかで迷いました。また、SNSトピックとSlackチャネルの紐づけ方も迷いました。あまり参考になりそうな資料がなかったので暫定として次のように設計しました。

**CloudWatchAlarm:SNSトピック=n:1**
**SNSトピック:Slackチャネル=1:1**
イメージはこんな感じです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884210/707aea25-8369-aa3f-8c8d-59ba41128fb7.png" width="500">
SNSトピックを複数にするメリットがなさそうな一方、複数にすると管理が煩わしそうなのでこの方法でいくことにしました。