AWSのELBを死活監視し、アラームをslackに通知する


目的

EC2へのパケット転送を行うELBの死活監視を行い、SNS(slack)に通知させて障害対応を早めるため、AWSのサービスで実装しました。

概要

全体の構成は以下の通りです。ターゲットグループとしてEC2を1台指定したELB(アプリケーションELB)に対して、CloudWatchで死活監視を行い、ダウンを検知したらlambdaを起動させ、SNS経由でslackに通知させるという内容です。lambdaで指定するslackのURLをKMSで暗号/復号化しています。

手順

概要図のサービスの矢印の順に作成していくイメージです。
1. CloudWatchでの死活監視の実装
2. slackの設定
3. lambda用のKMS作成
4. KMS用のIAMポリシーを作成
5. lambdaからSNSへの通知設定の実装

CloudWatchでの死活監視の実装

CloudWatchにて「アラームの作成」を選択し、メトリクスとして作成したELBの「HealthyHostCount」を選択します。
HealthyHostCountは「正常と見なされるターゲットの数」をカウントしており、私の環境ではターゲットが1台なので、閾値として「0以下」の時を指定して検知させます。

メトリクスを選択し、監視のパラメータを設定します。

アクションの設定として「新しいSNSトピック」を指定します。
※画像では既存のSNSトピックを選択し、エンドポイントとしてEメールも指定していますが、この画面から新しくSNSトピックを作成することが可能です。

slackの設定

参考にしたのは以下のサイトです。
https://dev.classmethod.jp/cloud/sns-messaging-slack/

以下のSlack APIのYour Apps画面から通知用のアプリを作成します。
https://api.slack.com/apps
アプリ名と通知させたいworkspaceを選択して下さい。

slack側から許可を求められますので、確認して許可してください。

アプリが作成されると、Basic Informationページに遷移します。今回のアプリではLambdaからslack宛にメッセージを送信したいので、Incoming Webhooksを選択してください。

Incoming Webhooksページにて、Activate Incoming WebhooksのスイッチをOnにしてAdd New Webhook to Workspaceをクリックし、チャンネル名を選択し、許可するをクリックします。
許可が完了すると以下の画面のようにslackの指定したチャンネルに対してpostでメッセージを投稿することが出来るようになります。

Webhook URLは後でlambdaの環境変数に指定するのでコピーしておいてください。

サンプル通りcurlを実行すると、対象のチャンネルに「Hello,World!」が投稿出来ることが確認できます。

lambdaの関数内でslackのURLを指定する際にKMSでURLを暗号/復号化する必要があるので、KMSで暗号鍵を作成します。

lambda用のKMS作成

AWSコンソールからKMSを選択し、カスタマー管理型のキーとしてキーの作成を選択します。キーのタイプは対照を選びます。

IAMロール作成時に指定するので、KMSのARNをコピーしておきます。

lambda用のIAMポリシーを作成

AWSコンソールからIAMポリシーを選択し、KMS用のIAMであることが分かるポリシー名をつけ、JSONタブにて以下の通りKMSのARNを指定して貼り付け、IAMポリシーを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "KMSのARN"
            ]
        }
    ]
}

作成後、以下の3つのポリシーをまとめてアタッチしてIAMロールを作成します。

  • CloudWatchReadOnlyAccess →    Cloudwatch参照用
  • AWSLambdaBasicExecutionRole →   lambda実行用
  • 自作のKMSポリシー →     KMSキーの暗号/復号化用

先ほど作成したKMSのキー管理者/キーユーザーとして、IAMロールを指定します。

lambdaからSNSへの通知設定の実装

AWSコンソールからlambdaを選択し、既存の設計図「cloudwatch-alarm-to-slack-python」を検索して使用します。

関数名を指定し、実行ロールとして作成したロールを指定し、SNSトリガーとしてCloudWatchで指定したSNSトピックを指定します。

lambdaの環境変数だけ指定すれば、Pythonの関数を修正しなくてもslackへの投稿が可能になります。

key Value
Slack channel 通知したいチャンネル名
kmsEncrptedHookUrl slackのwebhookURL

入力後にkmsEncrptedHookUrlの横の「Encrypt」をクリックするとURLがKMSキーで暗号化されます。関数内でこのURLを複合化し、slackに投稿を行います。

結果

ELBがダウンした際には、slackの指定したチャンネルにアラートが飛ぶようになりました。