EventBridgeのイベントデータをSNS経由でメール通知する

EventBridgeのイベントデータをSNS経由でメール通知する

EventBridgeのイベントデータをSNS経由でメール通知する

以下のページでEventBridgeからLambda関数を呼び出す方法をご紹介しました。

https://awstut.com/2022/12/05/integrating-two-lambda-functions-using-eventbridge

今回はEventBridgeとSNSを連携させて、イベントデートをメール通知する方法をご紹介します。

構築する環境

Diagram of email notification of EventBridge event data via SNS

基本的な構成は、冒頭でご紹介したページと同様です。

EventBridgeの連携先にSNSを指定し、イベントデータをメールで通知します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/102

テンプレートファイルのポイント解説

本ページでは、EventBridgeのイベントデータを、SNS経由でメール通知する方法を中心に取り上げます。

SNS

Resources:
  Topic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref MailAddress
          Protocol: email
      TopicName: !Ref Prefix
Code language: YAML (yaml)

SNSトピックを作成します。
トピックに通知先のメールアドレスを指定します。

詳細に関しましては、以下のページをご確認ください。

https://awstut.com/2022/07/30/introduction-to-sns-with-cfn-email

EventBridge

Resources:
  EventsRule:
    Type: AWS::Events::Rule
    Properties:
      EventBusName: !Ref EventBusName
      EventPattern:
        source:
          - !Ref Prefix
      Name: !Sub "${Prefix}-EventsRule"
      State: ENABLED
      Targets:
        - Arn: !Ref TopicArn
          Id: !Ref TopicName
Code language: YAML (yaml)

EventBridgeルールのターゲットに、先述のSNSトピックを指定します。

SNSのリソースベースポリシー

EventBridgeとSNSを連携させるためには、EventBridgeに対して、SNSにメッセージをパブリッシュする権限を与える必要があります。

Resources:
  TopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Principal:
              Service: events.amazonaws.com
            Action: sns:Publish
            Effect: Allow
            Resource: !Ref TopicArn
      Topics:
        - !Ref TopicArn
Code language: YAML (yaml)

EventBridgeにSNS関係のアクセス権限を与えるためには、リソースベースポリシーを利用します。

Lambda、Amazon SNS、Amazon SQS、および Amazon CloudWatch Logs リソースの場合、EventBridge はリソースベースのポリシーを使用します。

Amazon EventBridge のリソースベースのポリシーを使用する

なおSNSへのアクセス権を、アイデンティティベースのポリシーでは与えることはできません。
具体的には、仮にsns:Publishのアクションを許可するIAMロールを作成し、これをEventBridgeルールに関連づけたとしても、意図通りに動作しませんのでご注意ください。

(参考)Lambda関数

Resources:
  Function1:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          import boto3
          import datetime
          import json
          import os

          event_bus_name = os.environ['EVENT_BUS_NAME']
          detail_type = os.environ['DETAIL_TYPE']
          source = os.environ['SOURCE']

          client = boto3.client('events')

          def lambda_handler(event, context):
            detail = json.dumps(
              {
                'subject': 'EventBridge and SNS',
                'message': 'integration test.'
              }
            )

            entry = {
              'Time': datetime.datetime.now(),
              'Source': source,
              'Resources': [],
              'DetailType': detail_type,
              'Detail': detail,
              'EventBusName': event_bus_name
            }

            response = client.put_events(
              Entries=[entry,]
            )
            print(response)
      Environment:
        Variables:
          EVENT_BUS_NAME: default
          DETAIL_TYPE: eventbridge-sns-test
          SOURCE: !Ref Prefix
      FunctionName: !Sub "${Prefix}-function"
      Handler: !Ref Handler
      Runtime: !Ref Runtime
      Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)

PythonからEventBridgeにテストのメッセージを送信します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

https://awstut.com/2021/12/02/cloudformation-nested-stacks

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • EventBridgeルール:fa-102-EventRule
  • SNSトピック:fa-102
  • Lambda関数1:fa-102-function

メールアドレスの認証

SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。
指定したメールアドレスに、以下のような認証メールが送られてきます。

Detail of SNS 1.

「Confirm subscription」を押下して、認証を進めます。

Detail of SNS 2.

上記のページが表示されて、認証が完了したことがわかります。

リソース確認

AWS Management Consoleから各リソースを確認します。
まずSNSトピックを確認します。

Detail of SNS 3.

SNSトピックのサブスクライバーとして、メールアドレスが指定されています。

Detail of SNS 4.

アクセスポリシーを見ると、プリンシパルにEventBridgeが指定された上で、メッセージをパブリッシュすることが許可されています。
これでEventBridgeからSNSにイベントデータを発信することができます。

EventBridgeルールを確認します。

Detail of EventBridge 1.

ルールが正常に作成されていることがわかります。

ターゲットとして、SNSトピックが指定されていることも確認できます。

動作確認

準備が整いましたので、Lambda関数を実行します。

Detail of Lambda 1.

関数が正常に実行されました。

しばらく待機すると、指定したメールアドレスに以下のアドレスが届きました。

Detail of EventBridge 2.

確かにEventBridgeデータを、SNS経由でメール通知することができました。
メールのタイトルは「AWS Notification Message」、本文がJSON形式のイベントデータです。

まとめ

EventBridgeとSNSを連携させて、イベントデートをメール通知する方法をご紹介しました。