AWS S3 通知における s3:TestEvent のよくある落とし穴を避ける

AWS S3 通知における s3:TestEvent のよくある落とし穴を避ける

S3 バケットにイベント通知を設定すると、S3 から s3:TestEvent メッセージが自動的に送信されます。このテストメッセージを適切に扱わないと、予期しない問題を引き起こすことがあります。

Takahiro Iwasa
3 min read

S3 バケットにイベント通知を設定すると、S3 から s3:TestEvent メッセージが自動的に送信されます。このテストメッセージを適切に扱わないと、予期しない問題を引き起こすことがあります。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-content-structure.html

When you configure an event notification on a bucket, Amazon S3 sends a test message with the s3:TestEvent.

構築

CloudFormation スタックのテンプレートを作成します。

template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Example of CloudWatch events not queueing to SSE SQS
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
NotificationConfiguration:
QueueConfigurations:
- Event: 's3:ObjectCreated:Put'
Queue: !GetAtt Queue.Arn
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Queue:
Type: AWS::SQS::Queue
Properties:
QueueName: s3-event-notification-test-queue
ReceiveMessageWaitTimeSeconds: 20
QueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: '2008-10-17'
Statement:
- Effect: Allow
Principal:
Service: s3.amazonaws.com
Action:
- SQS:SendMessage
- SQS:ReceiveMessage
Resource: !GetAtt Queue.Arn
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
Queues:
- !Ref Queue

スタックをデプロイします。

Terminal window
aws cloudformation deploy \
--template-file template.yaml \
--stack-name s3-event-notification-test

テスト

SQS のメッセージを確認し、設定が機能していることを確かめます。

Terminal window
aws sqs receive-message \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/{AccountId}/s3-event-notification-test-queue

バケットにオブジェクトを一つも追加していなくても、出力の中に s3:TestEvent メッセージが確認できるはずです。

{
"Messages": [
{
"MessageId": "...",
"ReceiptHandle": "...",
"MD5OfBody": "...",
"Body": "{\"Service\":\"Amazon S3\",\"Event\":\"s3:TestEvent\",\"Time\":\"2020-12-29T18:53:47.874Z\",\"Bucket\":\"s3-event-notification-test-bucket-xxxxxxxx\",\"RequestId\":\"...\",\"HostId\":\"...\"}"
}
]
}

後片付け

作業後はスタックを削除します。

Terminal window
aws cloudformation delete-stack --stack-name s3-event-notification-test

まとめ

SQS のイベント通知を持つ S3 バケットをデプロイし、キューをポーリングしてみたところ、オブジェクトが一つもアップロードされていない段階で s3:TestEvent メッセージが届いていました。このテンプレートの NotificationConfigurations3:ObjectCreated:Put にのみ購読していますが、この最初のメッセージには対応する Event フィールドすら存在しません。これは、通知設定がアタッチされた瞬間に、実際にどのイベントタイプが要求されていたかに関わらず、S3 が自動的に送信するものです。このキューを消費する Lambda やアプリケーションのコードは Event フィールドを確認し、s3:TestEvent をスキップするか明示的に処理する必要があります。このメッセージは実際のオブジェクトが届き始めるタイミングではなく、スタックが最初にデプロイされたタイミングで届くため、実際のオブジェクト作成ペイロードと同じように扱ってしまうとパースエラーが発生します。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.