S3イベント通知の4つの送信先 – SNS/SQS/Lambda/EventBridge
以下のページで、S3のイベント通知機能を使用して、アップロードされた画像から、自動的にサムネイル画像を作成する構成をご紹介しました。
上記ページでは、イベント通知でLambda関数をトリガーする構成でした。
今回はイベント通知の4つの送信先を確認します。
構築する環境
S3バケットを作成します。
イベント通知機能を有効化します。
通知の送信先として、以下の4リソースを指定します。
- Lambda関数
- SQS
- SNS
- EventBridge
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/113
テンプレートファイルのポイント解説
S3バケット
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName: !Ref BucketName
NotificationConfiguration:
LambdaConfigurations:
- Event: "s3:ObjectCreated:*"
Function: !Ref Function1Arn
QueueConfigurations:
- Event: "s3:ObjectTagging:*"
Queue: !Ref QueueArn
TopicConfigurations:
- Event: "s3:ObjectRemoved:*"
Topic: !Ref TopicArn
EventBridgeConfiguration:
EventBridgeEnabled: true
Code language: YAML (yaml)
4つの通知先を指定します。
Lambda関数への通知は、LambdaConfigurationsプロパティを使用します。
イベント通知する条件ですが、「s3:ObjectCreated:*」を設定し、バケットにオブジェクトが設置された場合に、関数がトリガーされます。
SQSへの通知は、QueueConfigurationsプロパティを使用します。
イベント通知する条件ですが、「s3:ObjectTagging:*」を設定し、バケット内のオブジェクトにタグ設定(追加など)された場合に、SQSキューにメッセージが送信されます。
SNSへの通知は、TopicConfigurationsプロパティを使用します。
イベント通知する条件ですが、「s3:ObjectRemoved:*」を設定し、バケットからオブジェクトが削除された場合に、SNSトピックにメッセージが送信されます。
EventBridgeへの通知は、EventBridgeConfigurationプロパティを使用します。
このプロパティでEventBridgeへの通知を有効化します。
Lambda関数
Resources:
Function1:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Code:
ZipFile: |
def lambda_handler(event, context):
print(event)
FunctionName: !Sub "${Prefix}-Function1"
Handler: !Ref Handler
Runtime: !Ref Runtime
Role: !GetAtt Function1Role.Arn
Code language: YAML (yaml)
イベント通知先のLambda関数です。
Lambda関数で実行するコードをインライン形式で記載します。
詳細につきましては、以下のページをご確認ください。
実行するコードですが、eventオブジェクトの中身を出力するシンプルな内容です。
ちなみに後述のSQS・SNS・EventBridgeでも、同様の内容の関数を実行します。
通知先をLambda関数にする場合の権限について確認します。
S3イベント通知でLambda関数をトリガーするということは、S3バケットがLambda関数を実行するという意味になります。
これはLambdaのリソースベースポリシーによって設定します。
Resources:
S3Permission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Function1
Action: lambda:InvokeFunction
Principal: s3.amazonaws.com
SourceArn: !Sub "arn:aws:s3:::${BucketName}"
Code language: YAML (yaml)
先述のバケットがこの関数を呼び出すことを許可する内容です。
SQS
Resources:
Queue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub "${Prefix}-Queue"
ReceiveMessageWaitTimeSeconds: !Ref ReceiveMessageWaitTimeSeconds
VisibilityTimeout: !Ref VisibilityTimeout
Code language: YAML (yaml)
イベント通知先のキューです。
SQSに関する基本的な事項については、以下のページをご確認ください。
通知先をSQSにする場合の権限について確認します。
S3イベント通知をSQSキューにメッセージングするということは、S3バケットがキューにメッセージを送信するという意味になります。
これはアクセスポリシーによって設定します。
Resources:
QueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Statement:
- Action:
- sqs:SendMessage
Condition:
ArnLike:
aws:SourceArn: !Sub "arn:aws:s3:::${BucketName}"
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
Effect: Allow
Resource: !GetAtt Queue.Arn
Principal:
Service:
- s3.amazonaws.com
Queues:
- !Ref Queue
Code language: YAML (yaml)
先述のバケットがこのキューにメッセージを送信することを許可する内容です。
今回はSQSキューにメッセージが格納された時に、自動的にLambda関数をトリガーするように設定します。
Resources:
EventSourceMapping:
Type: AWS::Lambda::EventSourceMapping
Properties:
BatchSize: !Ref BatchSize
Enabled: true
EventSourceArn: !Ref QueueArn
FunctionName: !Ref Function2
Code language: YAML (yaml)
詳細につきましては、以下のページをご確認ください。
SNS
Resources:
Topic:
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub "${Prefix}-Topic"
Code language: YAML (yaml)
イベント通知先のトピックです。
SNSに関する基本的な事項については、以下のページをご確認ください。
特別な設定は行いません。
通知先をSNSにする場合の権限について確認します。
S3イベント通知をSNSトピックにメッセージングするということは、S3バケットがトピックにメッセージを送信するという意味になります。
これはアクセスポリシーによって設定します。
Resources:
TopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Statement:
- Action:
- sns:Publish
Condition:
ArnLike:
aws:SourceArn: !Sub "arn:aws:s3:::${BucketName}"
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
Effect: Allow
Resource: !Ref Topic
Principal:
Service:
- s3.amazonaws.com
Topics:
- !Ref Topic
Code language: YAML (yaml)
トピックのサブスクリプションはLambda関数を指定します。
Resources:
TopicSubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: !GetAtt Function3.Arn
Protocol: lambda
TopicArn: !Ref SNSTopicArn
Code language: YAML (yaml)
詳細につきましては、以下のページをご確認ください。
EventBridge
Resources:
EventsRule:
Type: AWS::Events::Rule
Properties:
EventBusName: !Ref EventBusName
EventPattern:
source:
- aws.s3
Name: !Sub "${Prefix}-EventsRule"
State: ENABLED
Targets:
- Arn: !Ref Function4Arn
Id: !Ref Function4
Code language: YAML (yaml)
EventBridgeルールを作成します。
EventBridgeルールに関する基本的な事項は、以下のページをご確認ください。
今回はsourceの値が「aws.s3」であるルールを設け、これにマッチしたイベントをターゲットであるLambda関数に送信します。
ターゲットにLambda関数を指定する場合、EventBridgeが関数を呼び出すという挙動になります。
そのためEventBridgeに関数を呼び出す権限を与える必要があります。
Resources:
EventsRulePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Function4
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt EventsRule.Arn
Code language: YAML (yaml)
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- S3バケット:fa-113
- SQSキュー:fa-113-Queue
- SNSトピック:fa-113-Topic
- EventBridgeルール:fa-113-EventsRule
- Lambda関数1:fa-113-Function1
AWS Management Consoleから各リソースを確認します。
S3バケットを確認します。
4つの通知先が有効化されていることがわかります。
SQSを確認します。
SQSキューが正常に作成されています。
Lambdaトリガーとして、関数2が指定されていることもわかります。
つまりS3バケットからこのSQSキューに対して、イベント通知が送信されると、自動的に関数2が実行されるということになります。
SNSを確認します。
SNSトピックが正常に作成されています。
トピックのサブスクライバーとして、Lambda関数3が指定されていることがわかります。
つまりS3バケットからこのSNSトピックに対して、イベント通知が送信されると、自動的に関数3が実行されるということになります。
EventBridgeを確認します。
EventBridgeルールが正常に作成されています。
ルールのターゲットとして、Lambda関数4が指定されていることがわかります。
つまりS3バケットからルールにマッチするイベントが発信されると、自動的に関数4が実行されるということになります。
動作確認
準備が整いましたので、S3イベント通知のテストを行います。
Lambda関数へイベント通知
Lambda関数にイベント通知を行います。
今回、Lambda関数に通知する条件を「s3:ObjectCreated:*」としていますので、オブジェクトを配置します。
オブジェクトが設置されたことを受けて、関数1が自動的に実行されているはずです。
関数1の実行ログを確認します。
確かに関数1が実行されています。
eventNameの値を見ると、「ObjectCreated:Put」が確認できます。
このようにS3イベント通知を受けて、自動的にLambda関数を実行することができます。
SQSへイベント通知
SQSキューにイベント通知を行います。
今回、キューに通知する条件を「s3:ObjectTagging:*」としていますので、オブジェクトにタグを設定します。
キーが「foo」、値が「bar」というタグを設定しました。
これを受けてSQSキューにメッセージが送信されたはずです。
そしてこのキューにはLambdaトリガーを設定していますので、Lambda関数2が実行されるはずです。
関数2の実行ログを確認します。
確かに関数2が実行されています。
eventNameの値を見ると「ObjectTagging:Put」、Eventの値を見ると「s3:TestEvent」が確認できます。
このようにS3イベント通知を受けて、自動的にSQSキューにメッセージを通知することができます。
なお「s3:TestEvent」については、AWS公式では、以下の通り説明されています。
通知が最初に有効になったとき、s3:TestEvent が発生します。
Amazon SQS、Amazon SNS、Lambda を使用します
SNSへイベント通知
SNSトピックにイベント通知を行います。
今回、トピックに通知する条件を「s3:ObjectRemoved:*」としていますので、オブジェクトを削除します。
オブジェクトが削除されました。
これを受けてSNSトピックにメッセージが送信されたはずです。
そしてこのトピックのサブスクリプションにLambda3を設定していますので、Lambda関数3が実行されるはずです。
関数3の実行ログを確認します。
確かに関数3が実行されています。
eventNameの値を見ると、「ObjectRemoved:Delete」が確認できます。
このようにS3イベント通知を受けて、自動的にSNSトピックにメッセージを通知することができます。
EventBridgeへイベント通知
EventBridgeにイベント通知を行います。
今回、EventBridgeへの通知を有効化していますので、今までの操作(オブジェクト追加、タグ設定、オブジェクト削除)の度に通知されているはずです。
そしてEventBridgeルールのターゲットにLambda関数4を設定していますので、Lambda関数4が3回実行されるはずです。
確かに関数4が実行されています。
detail-typeの値を見ると、「Object Created」、「Object Tags Added」、「Object Deleted」が確認できます。
このようにS3イベント通知を受けて、自動的にEventBridgeにメッセージを通知することができます。
まとめ
S3イベント通知の4つの送信先を確認しました。