はじめに
CloudWatchアラームでモニタリングして、アラームが発生したらslackへ通知させる設定をしたいと思います。
最初はCloudWatchからLambdaを直接実行できるのかなと思ったのですが、直接実行できるのはイベントだけみたいです。アラームから直接Lambdaを実行することはできませんでした。なので、SNS経由で実行する必要があります。
イメージとしては以下のような構成になります。
slack への通知設定
図の右側(エンド側)から順番に設定していく必要があります。なのでまずはslackの設定を行います。
channel の用意
今回は #lambda2slack という名前でchannelを用意します。
とりあえず、 slack への通知は Incoming Webhook という機能が slack API から提供されているのでそれを使って行います。
Incoming Webhook の設定に関しては前にQiitaに書いたのでそちらを参考にしてください。
参考:slackのIncoming Webhookを試してみた。
プログラムの作成
Incoming webhook を使うのに、 python のライブラリで slackweb というのがあるみたいです。今回はこれを使って行うことにしました。
とりあえずインストール。
$ pip install slackweb
インストールできたらコマンドで試してみます。
$ python
Python 3.6.2 (default, Sep 28 2017, 02:02:02)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import slackweb
>>> slack = slackweb.Slack(url="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX")
>>> slack.notify(text="hello, kohei!!")
'ok'
slack.notify で引数に渡した値(ここでは"hello, kohei!!")が先ほど作成したslackのchannelへ通知されたらOKです。
とりあえず、今回はCloudWatch からslackへ通知を行うことを目的としているので、これ以上のプログラミングは行わずに次へ進みます。
プログラムの関数化
Lambdaで実行できるようにするには、プログラムを関数として扱えるようにする必要があります。
先ほどコマンドで実行した内容を以下のように関数化して保存します。
$ vim lambda2slack.py
---
import slackweb
def lambda_handler(ecent, context):
slack = slackweb.Slack(url="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX")
slack.notify(text="hello, kohei!!")
関数として利用できるか確認をしてみます。
$ python
>>> from lambda2slack import lambda_handler
>>> lambda_handler(None, None)
先ほどと同じようにslackへ通知が届いたらOKです。
Lambdaの設定
slackへ通知ができるところまで確認ができたので、Lambdaの設定を行います。
zip圧縮
今回の場合、slackwebはデフォルトで利用できるライブラリではありません。そのためコードだけアップしてもエラーとなってしまいます。そういう場合はライブラリも一緒にzipファイルとして圧縮してアップロードしてあげることで解決です。
まずは、アップロード用のディレクトリを作成し、そこへ必要なライブラリとプログラムを入れます。
$ mkdir upload
$ cd upload
今回必要となるslackwebのライブラリをアップロード用ディレクトリへダウンロードします。
$ pip install slackweb -t .
Collecting slackweb
Using cached slackweb-1.0.5.tar.gz
Installing collected packages: slackweb
Running setup.py install for slackweb ... done
Successfully installed slackweb-1.0.5
先ほど作成した関数化したプログラムファイルも入れます。
$ cp ../lambda2slack.py ./
配置が完了したら以下みたいになってるはずです。
$ ls
lambda2slack.py slackweb slackweb-1.0.5-py3.6.egg-info
揃ったらzip圧縮します。
$ zip -r upload.zip *
adding: lambda2slack.py (deflated 42%)
adding: slackweb/ (stored 0%)
adding: slackweb/__init__.py (deflated 4%)
adding: slackweb/__pycache__/ (stored 0%)
adding: slackweb/__pycache__/__init__.cpython-36.pyc (deflated 15%)
adding: slackweb/__pycache__/slackweb.cpython-36.pyc (deflated 41%)
adding: slackweb/slackweb.py (deflated 60%)
adding: slackweb-1.0.5-py3.6.egg-info/ (stored 0%)
adding: slackweb-1.0.5-py3.6.egg-info/dependency_links.txt (stored 0%)
adding: slackweb-1.0.5-py3.6.egg-info/installed-files.txt (deflated 43%)
adding: slackweb-1.0.5-py3.6.egg-info/PKG-INFO (deflated 48%)
adding: slackweb-1.0.5-py3.6.egg-info/SOURCES.txt (deflated 46%)
adding: slackweb-1.0.5-py3.6.egg-info/top_level.txt (stored 0%)
upload.zipというのが出来上がっているので、あとはこれをLambdaへアップロードすればOKです。
$ ls
lambda2slack.py slackweb-1.0.5-py3.6.egg-info
slackweb upload.zip
Lambdaへアップロード
AWS管理画面から、Lmabdaのサービス画面へ行き、**「関数の作成」**をクリックします。
今回はテンプレなどは使わないので**「一から作成」**をクリックします。
名前を入力し、ロールで**「カスタムロールの作成」**を選択します。
するとIAMポリシー作成画面へ移動するのでそこでポリシーを作成します。
今回の場合はデフォルト(ログ出力権限)で十分です。
**「既存のロール」のところが先ほど作成したロールになっているのを確認して「関数の作成」**を行います。
「関数コード」のランタイムを**「python 3.6」、コードエントリ タイプを「.zipファイルをアップロード」、ハンドラを「lambda2slack.lambda_handler」にして先ほどzipにしたファイルをアップロードします。
アップロードができたら「保存してテスト」**をクリックします。
ちなみにこの時点でslackへも通知が届いているはずです。
SNSで通知設定
次はCloudWatchからlambdaを実行できるようにするために、SNSトピックを作成し、そこへ作成したLambdaを登録します。
AWS管理画面から、SNSのサービス画面へ行きます。
Topic nameを入力したら**「Create topic」**でトピックを作成します。
トピックが作成できたら**「Create subscription」**をクリックします。
Protocolを**「AWS Lambda」、Endpointを先ほど作成したLambda関数(lambda2slack)を指定して「Create subscription」**で作成します。
以上でSNSの設定は完了です。
CloudWatchからの呼び出し
AWS管理画面から、CloudWatchのサービス画面へ行き、アラームから**「アラームの作成」**を行います。
メトリクスの選択でアラームでチェックしたいメトリクスを指定します。
今回は通知を確認したかったのでLambdaの呼び出し(Invocations)を指定し閾値を_≧1_にしました。
アラームの定義で閾値を設定したらアクションで通知の送信先を先ほど作成したSNSトピックの**lambda2slackを指定してから「アラームの作成」**をクリックして作成します。
これでCloudWatchの設定も完了し、一連の設定が完了しました。
おそらく先ほどLambdaを登録した際にテストで実行しているので、設定がうまくできているとslackへ通知が届くとお思います。
おわりに
以上が「CloudWatchアラームで検知」→「slackへ通知」を行うための設定です。
本来ならURLなどは変数にして「KMSで暗号化」とかするのが良いみたいですが、まずは最低限のサービスでシンプルに構築してみたほうが仕組みがわかって良いかなと思いました。
ここから徐々に他のサービスを利用したり、プログラムを書いたりして行けたらいいかなと思います。