S3バケットにイベント通知を設定する – AWS SDK for JavaScript v3
既存S3バケットにイベント通知を設定します。
プロジェクト作成
npmプロジェクト作成します。
npm init -y
@aws-sdk/client-s3をインストールします。
npm i @aws-sdk/client-s3
ESMにするためにpackage.jsonに"type": "module"を1行追加します。
{
"name": "lambda-s3-notification",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"type": "module",
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-s3": "^3.129.0"
}
}
Lambda(node.js v16)
バケット名、LambdaのARNは設定が必要です。
import { PutBucketNotificationConfigurationCommand , S3Client } from '@aws-sdk/client-s3'
const bucketname = 'バケット名'
export async function handler(event, context) {
const client = new S3Client({
region: 'ap-northeast-1'
})
const input = {
Bucket: bucketname,
NotificationConfiguration: {
LambdaFunctionConfigurations: [{
LambdaFunctionArn: 'LambdaのARN',
Events: ['s3:ObjectCreated:Put'] // ここではPut
}]
}
}
const command = new PutBucketNotificationConfigurationCommand(input)
const response = await client.send(command)
return {
statusCode: 200,
body: `Hello`
}
}
レスポンス
こんな感じです。httpStatuscodeが200ならうまくいっているはずです。
{
'$metadata': {
httpStatusCode: 200,
requestId: undefined,
extendedRequestId: 'vUnKAdb+fmmacGYe4ebD/8thtUNFWnttlPBcda5zIWTSE5tuUUvLlqGFDatcZQd/WvKKxmDrcK4=',
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
}
}
LambdaFunctionArnで指定したLambdaのリソースベースのポリシーステートメントを作成しておく必要があります。
この設定がされていない場合、「Unable to validate the following destination configurations」エラーとなります。
注意
既に設定されているトリガーの設定は上書きされてしまい、削除されてしまいます。 上書きされない様、追加されるLambdaにします。↓
既存のトリガー設定を保持しつつ、新規トリガーを追加するLambda(node.js v16)
既存のイベント通知を取得して、その配列に新規イベント通知をpushしてPutBucketNotificationConfigurationCommandで全登録します。
import { GetBucketNotificationConfigurationCommand, PutBucketNotificationConfigurationCommand , S3Client } from '@aws-sdk/client-s3'
const bucketname = 'バケット名指定'
export async function handler(event, context) {
const client = new S3Client({
region: 'ap-northeast-1'
})
let input, command,response
input = {
Bucket: bucketname
}
command = new GetBucketNotificationConfigurationCommand(input)
response = await client.send(command)
input = { // 追加したいイベント通知
Bucket: bucketname,
NotificationConfiguration: {
LambdaFunctionConfigurations: [{
LambdaFunctionArn: 'LambdaのARN',
Events: ['s3:ObjectCreated:Put'], // ここではPut
Filter: {
Key:{
FilterRules: [
{ Name: 'Prefix', Value: 'hoge/' },
{ Name: 'Suffix', Value: '.csv' }
]
}
}
}]
}
}
if(response.LambdaFunctionConfigurations !== undefined) { // Lambdaイベント通知が存在する場合
input.NotificationConfiguration.LambdaFunctionConfigurations.push(...response.LambdaFunctionConfigurations) // 配列に配列追加
}
command = new PutBucketNotificationConfigurationCommand(input)
await client.send(command)
return {
statusCode: 200,
body: `Hello`
}
}
イベントタイプが重複していると「Configurations overlap. Configurations on the same bucket cannot share a common event type.」エラーとなります。
警告
イベント通知で実行されるlambdaがS3バケットにファイルをプットする場合は無限ループが発生する可能性がありますので注意が必要です。
通知が通知をトリガーするのと同じバケットに書き込むと、実行ループが発生する可能性があります。例えば、オブジェクトがアップロードされるたびにバケットで Lambda 関数をトリガーし、その関数によってオブジェクトがバケットにアップロードされると、その関数によって間接的にその関数自体がトリガーされます。これを回避するには、2 つのバケットを使用するか、受信オブジェクトで使用されるプレフィックスにのみ適用されるようにトリガーを設定します。
Lambdaが実行されないケース
「s3:ObjectCreated:Put」だけだとLambdaが実行されないケースがあります。
大きいサイズのファイルがPUTされた場合は、「s3:ObjectCreated:CompleteMultipartUpload」となるようです。
https://tech.trustbank.co.jp/entry/2022/04/05/160000
参考サイト
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/classes/putbucketnotificationconfigurationcommand.html https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/modules/notificationconfiguration.html https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/modules/lambdafunctionconfiguration.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES20xx),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^





コメント