Help us understand the problem. What is going on with this article?

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

More than 5 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 に日本語が入っていると、うまく通知されないぽい

参考

tmtysk
bldt
"Your growth, Improve the world" をビジョンに掲げ、自社事業やシステム開発サービスを提供しています
https://bldt.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした