AWS S3 通知における s3:TestEvent のよくある落とし穴を避ける
S3 バケットにイベント通知を設定すると、S3 から s3:TestEvent メッセージが自動的に送信されます。このテストメッセージを適切に扱わないと、予期しない問題を引き起こすことがあります。
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 スタックのテンプレートを作成します。
AWSTemplateFormatVersion: "2010-09-09"Description: Example of CloudWatch events not queueing to SSE SQSResources: 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スタックをデプロイします。
aws cloudformation deploy \ --template-file template.yaml \ --stack-name s3-event-notification-testテスト
SQS のメッセージを確認し、設定が機能していることを確かめます。
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\":\"...\"}" } ]}後片付け
作業後はスタックを削除します。
aws cloudformation delete-stack --stack-name s3-event-notification-testまとめ
SQS のイベント通知を持つ S3 バケットをデプロイし、キューをポーリングしてみたところ、オブジェクトが一つもアップロードされていない段階で s3:TestEvent メッセージが届いていました。このテンプレートの NotificationConfiguration は s3:ObjectCreated:Put にのみ購読していますが、この最初のメッセージには対応する Event フィールドすら存在しません。これは、通知設定がアタッチされた瞬間に、実際にどのイベントタイプが要求されていたかに関わらず、S3 が自動的に送信するものです。このキューを消費する Lambda やアプリケーションのコードは Event フィールドを確認し、s3:TestEvent をスキップするか明示的に処理する必要があります。このメッセージは実際のオブジェクトが届き始めるタイミングではなく、スタックが最初にデプロイされたタイミングで届くため、実際のオブジェクト作成ペイロードと同じように扱ってしまうとパースエラーが発生します。
Related posts
CloudFront署名付きURL経由でS3にアップロードする
CloudFrontの署名付きURLを使えば、独自ドメイン経由でS3にアップロードできます。S3の直接の署名付きURLが使えない場合に有用です。
Cognito User PoolsとOIDCでSlackサインインを実装する
Cognito user poolをOIDC経由でSlackと連携させ、"Sign in with Slack"をAmplifyでNext.jsアプリに組み込みます。
Lambda Web AdapterでFastAPIをAWS Lambdaにデプロイする
Lambda Web Adapterを使うと、FastAPIで書いたAPIバックエンドをコンテナのまま単一のLambda関数にデプロイできます。
API Gateway WebSocket:モック統合の実装
バックエンドのLambdaを一切使わず、モック統合のみでAPI Gateway WebSocket APIを構築し、あらかじめ用意されたレスポンスを返します。
AWS EventBridge Scheduler:スケジュールに沿ってEC2を起動・停止する
Lambdaを介さずEventBridge SchedulerがEC2 APIを直接呼び出すことで、cronスケジュールに従ってEC2インスタンスを起動・停止します。
