CloudWatchアラームをSlackに通知する方法:ステップバイステップガイド
今さらながら、CloudWatchのアラームをSlackに連携する手順を記載します。
今回は、AWSのアプリケーションロードバランサーの「UnHealthyHostCount」 が1以上のときにSlackに通知されるようにします。具体的にはロードバランサー配下にEC2が2台配置されており、そのEC2のどちらかがエラーでアクセス出来ない場合にその状態を検知するイメージです。
Slackへ連携する方法としては、「AWS Chatbot」を使用する方法と「AWS Lambda」を使用する方法がありますが、今回は「AWS Lambda」を使用してみます。
AWS CloudWatchアラームをSNSトピック経由でLambda関数に連携し、Lambda関数がSlackのWebhookに通知を送信することで、リアルタイムでアラートを受信します。
AWS SNSのトピックを作成
SNS(Simple Notification Service) でトピックの新規作成をします。
a.トピックの作成をします。
- タイプで[スタンダード]を選択する。
- 名前を記入する。
- 表示名を記入する。
[トピックの作成]をクリックし、トピックの作成が一旦完了です。
CloudWatchアラームの設定
CloudWatchで新しいアラームを作成し、作成したSNSトピックを通知先として設定します。
CloudWatchでアラームの新規作成をします。
ステップ1:メトリクスと条件の指定
メトリクスと条件の指定で [メトリクスの選択] をクリックします。
メトリクスで「UnHealthyHostCount」を検索し、[ApplicationELB > AppELB 別、TG 別メトリクス] をクリックします。
引き続き、メトリクスと条件の指定を行います。
- 名前空間は「AWS/ApplicationELB」が設定される。
- メトリクス名を入力する。
- TargetGroupを選択する。
- LoadBalancerを選択する。
- 統計は「最大」を選択する。
- 期間は「1分」を選択する。
条件を設定します。
- しきい値の種類は「静的」を選択する。
- UnHealthyHostCount が次の時…は「以上」を選択する。
- …よりも「1」を入力する。
[次へ]をクリックします。
ステップ2:アクションの設定
通知を設定します。
- アラーム状態トリガーは「アラーム状態」を選択する。
- 次のSNSトピックに通知を送信は「既存のSNSトピックを選択」を選択する。
- 通知の送信先を選択する。(先ほど作成したSNSトピック)
[次へ]をクリックします。
ステップ3:名前と説明を追加
名前と説明を設定します。
- アラーム名を入力する。
[次へ]をクリックします。
ステップ4:プレビューと作成
プレビューを確認し、設定内容に問題無ければ、[アラームの作成]をクリックします。
SlackのIncoming Webhookの作成
Slackの「Incoming Webhooks」アプリをインストールし、Webhook URLを取得します。
Slackの[ ツールと設定 > アプリを管理する ]をクリックします。
Slack側の画面に遷移するので、[カスタムインテグレーション]を選択します。
[Incoming Webhook]を選択します。
[Salckに追加]をクリックします。
Slackチャンネルを選択し[Incoming Webhook インテグレーションの追加]をクリックします。
「Webhook URL」の確認をします。
「Webhook URL」は、後ほどLambda関数で使用します。
Lambda関数の作成
AWS Lambda関数を作成し、SNSトピックからの通知を受信してSlack Webhookに送信するロジックを実装します。
[関数の作成]をクリックします。
関数を作成します。
- 「一から作成」を選択する。
- 関数名を入力する。
- ランタイムは「Node.js 20.x」を選択する。
- アーキテクチャは「x86_64」を選択する。
上記設定後、[関数の作成]をクリックします。
コードを書きます。
コードは下記で動きます。
※ /services/YOUR/SLACK/WEBHOOK
は「Webhook URL」で置き換えます。
import https from 'https';
export const handler = async (event) => {
const message = JSON.parse(event.Records[0].Sns.Message);
const postData = JSON.stringify({
text: `CloudWatch Alert: ${message.AlarmName}\n${message.NewStateReason}`
});
const options = {
hostname: 'hooks.slack.com',
path: '/services/YOUR/SLACK/WEBHOOK',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
res.on('data', (d) => process.stdout.write(d));
res.on('end', resolve);
});
req.on('error', (e) => reject(e));
req.write(postData);
req.end();
});
};
Lambdaのテストイベント作成
ここまでの設定が正しいかどうか、テストイベントを作成して動作確認します。
テストを作成します。
- イベントアクションをテストで「新しいイベントを作成」を選択する。
- イベント名を入力する。
- イベント共有の設定は「プライベート」を選択する。
- イベントJSONの内容は下記に記します。
下記がテストイベント用JSONです。
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-west-2:123456789012:example-topic",
"Sns": {
"Type": "Notification",
"MessageId": "11112222-3333-4444-5555-666677778888",
"TopicArn": "arn:aws:sns:us-west-2:123456789012:example-topic",
"Subject": "Test SNS Notification",
"Message": "{\"AlarmName\":\"ExampleAlarm\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (5.0) was greater than or equal to the threshold (5.0).\"}",
"Timestamp": "2024-05-23T12:34:56.789Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"UnsubscribeUrl": "EXAMPLE",
"MessageAttributes": {
"key": {
"Type": "String",
"Value": "value"
}
}
}
}
]
}
上記で保存し、テスト実行すると、下記のようにSlackに通知されました。
SNSトピックをトリガーとしてLambda関数に追加
作成済のSNS「UnHealthyHostCount」にサブスクリプションを作成しするため[サブスクリプションの作成]をクリックします。
サブスクリプションを作成します。
詳細
- トピックARNは既存のSNSのものが設定する。
- プロトコルで[AWS Lambda]を選択する。
- エンドポイントは先ほど作成した関数のARNを入力する。
上記を設定し、[サブスクリプションの作成]をクリックします。
以上で設定完了です。