EventBridgeのイベントデータをSNS経由でメール通知する
以下のページでEventBridgeからLambda関数を呼び出す方法をご紹介しました。
今回はEventBridgeと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トピックを作成します。
トピックに通知先のメールアドレスを指定します。
詳細に関しましては、以下のページをご確認ください。
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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- EventBridgeルール:fa-102-EventRule
- SNSトピック:fa-102
- Lambda関数1:fa-102-function
メールアドレスの認証
SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。
指定したメールアドレスに、以下のような認証メールが送られてきます。
「Confirm subscription」を押下して、認証を進めます。
上記のページが表示されて、認証が完了したことがわかります。
リソース確認
AWS Management Consoleから各リソースを確認します。
まずSNSトピックを確認します。
SNSトピックのサブスクライバーとして、メールアドレスが指定されています。
アクセスポリシーを見ると、プリンシパルにEventBridgeが指定された上で、メッセージをパブリッシュすることが許可されています。
これでEventBridgeからSNSにイベントデータを発信することができます。
EventBridgeルールを確認します。
ルールが正常に作成されていることがわかります。
ターゲットとして、SNSトピックが指定されていることも確認できます。
動作確認
準備が整いましたので、Lambda関数を実行します。
関数が正常に実行されました。
しばらく待機すると、指定したメールアドレスに以下のアドレスが届きました。
確かにEventBridgeデータを、SNS経由でメール通知することができました。
メールのタイトルは「AWS Notification Message」、本文がJSON形式のイベントデータです。
まとめ
EventBridgeとSNSを連携させて、イベントデートをメール通知する方法をご紹介しました。