ElastiCacheのイベント通知をLambdaを使ってフィルタしてみた

2020.04.14

コンニチハ 後藤です。

ElastiCacheにはイベントログをSNS経由で通知することが出来る機能があることご存じですか? この機能を利用することで、フェイルオーバや再起動が発生した場合もメール等で通知を受け取ることが出来ます。

しかし、このSNS通知はRDSのイベントサブスクリプションとは違い、全てのイベントログを通知します。 そのため、毎日取得しているスナップショット取得のログ等も通知されてしまいます。

そこで、今回はLambdaを使用してイベントログをフィルタし、特定のイベントログのみ通知してみました。

構成

SNSトピック作成

構成図に記載あるように、今回はトピックを2つ用意します。
(1) ElastiCacheからイベントログを受け取り、Lambdaに送信するSNSトピック
(2) Lambdaから特定イベントログのみ受け取り、メールを送信するSNSトピック

ElastiCacheのSNS通知を設定

↑で作成したSNSトピック(1)をElastiCacheのSNS通知に設定します。

Lambdaを設定

今回はPython3.8でLambdaを実行しています。

import boto3
import json
import os

sns = boto3.client('sns')

def lambda_handler(event, context):
    message = event['Records'][0]['Sns']['Message']
    if "FailoverComplete" in message:
        print("send mail")
        response = sns.publish(
            TopicArn = os.environ['sns_topic'],
            Message = message,
            Subject = os.environ['subject']
        )
    else:
        print("not send mail")
        print(message)

今回はフェイルオーバ完了を知らせる[FailoverComplete]が発生した場合、メールを送信するように設定しました。
処理を分かり易くするため、メール送信の処理が入った場合 send mail , 入らなかった場合 not send mail とCloudWatchLogsに出力するようにしています。

ElastiCacheのイベントログについては、以下ドキュメントをご参照ください。
ElastiCacheドキュメント イベント通知とAmazon SNS

Lambdaの環境変数でメッセージ送信先のSNSトピック名とメール件名を設定しています。

また、LambdaからSNSにメッセージを送信するため、LambdaのIAMロールにSNSの権限を付与します。
今回は検証のため、FullAccessで付与しております。

挙動を確認してみる

テストとして、ElastiCacheに手動スナップショットと手動フェイルオーバを実行をしてみました。

・手動スナップショット
スナップショット取得後にCloudWatchLogsを確認すると、メール通知処理には入っておらず、イベント内容がCloudWatchLogsに出力されていました。

・手動フェイルオーバ
こちらも実行後にCloudWatchLogsを確認すると、メール通知に入っていることがわかりました。

実際にメールを確認してみるとSNSからメールが届いていることが確認できました。

まとめ

ElastiCacheのSNS通知をLambdaを使用して特定イベントのみ通知出来るようにしました。
RDSのように特定イベントのみ通知出来るようになればいいのですが……無ければ作るのです
この記事が誰かのお役立てば幸いです。