Edited at

CloudWatchのAlertをAWS Lambda経由でSlackに飛ばす

More than 3 years have passed since last update.

AWS Lambda使ってCloudWatchのAlertをSlackに飛ばしてみた

この記事を読んで、「まさしくコレがやりたかった!」と思いトライしてみたが、S3 でロックファイル管理するなど、結構高機能なつくりのようだったので、もうちょっと単純なつくりにしたいと考えた。

と思ったら、 AWS Lambda function for forwarding SNS notifications to Slack なるコードを発見したので、少し改変して使わせていただくことにした、という話。


やりたいこと


  • CloudWatch の Alert は諸々設定済みで、通知先の Topic には Email の Subscription が設定してある

  • この Topic に Slack 通知する Lambda function の Subscription を追加したい


手順


Slack の WebHooks integration をつくる

https://slack.com/services/new から Incoming WebHooks の integration を作成しておく。アイコンや名前は適当。

Kobito.9rYp2k.png


Lambda function を登録する

AWS ダッシュボードで Create a Lambda function ボタンから Lambda function を登録する。AP リージョンはまだ提供されていないが、リージョン跨ぎで SNS Subscription 登録できるので、us-east-1 とかどこでも OK。

ブラウザ上のエディタで Lambda function を記述する。名前などは適当。

Gist のコードそのままでも良いが、これだと、SNS にポストされる JSON がそのまま Slack に流れてきて読みづらいので、ちょっと整形して以下のコードにした。各 Alarm には description が設定されている想定。ソース中の、slack_url には、先に作成した WebHooks の URL を指定しておく。

console.log('Loading function');

const https = require('https');
const url = require('url');
const slack_url = 'https://hooks.slack.com/<webhook_url>';
const slack_req_opts = url.parse(slack_url);
slack_req_opts.method = 'POST';
slack_req_opts.headers = {'Content-Type': 'application/json'};

exports.handler = function(event, context) {
(event.Records || []).forEach(function (rec) {
if (rec.Sns) {
var req = https.request(slack_req_opts, function (res) {
if (res.statusCode === 200) {
context.succeed('posted to slack');
} else {
context.fail('status code: ' + res.statusCode);
}
});

req.on('error', function(e) {
console.log('problem with request: ' + e.message);
context.fail(e.message);
});

// この辺で適当にslack postするテキストを調整する.
var message = JSON.parse(rec.Sns.Message);
var status = message.NewStateValue;
if (status === "ALARM") {
status = ":exclamation: " + status;
}
if (status === "OK") {
status = ":+1: " + status;
}
var str = "*" +
status +
": " +
message.AlarmDescription +
"*" +
"\n" +
message.NewStateReason;

req.write(JSON.stringify({text: str}));

req.end();
}
});
};

Kobito.t6lspE.png

これを Basic execution role の function として登録する。role を作ってなければ、登録時に一緒につくる。


登録した Lambda function に SNS Topic を Subscribe 設定する

CloudWatch の Alarm 通知先になっている Topic に、作成した Lambda function を Subscribe させる。

Kobito.CYM5pM.png


動作イメージ

Kobito.c8O4gA.png


注意事項


  • AlarmDescription に日本語が入っていると、うまく通知されないぽい


参考