この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、AWS事業本部@福岡オフィスのべこみん(@beco_minn)です。
最近はCDK楽しいマンになってます。
さて、皆さんは「CDKを使って、既存S3バケットのイベントドリブンでLambda関数を実行したいな〜」と思ったことはないですか?
今回は僕がそう思った時にハマったことを共有します。
ちなみに本記事で使用している言語はTypeScriptです。
いきなりまとめ
- CDKを使って既存S3バケットのイベントをトリガーにLambda関数をキックしたい時は、S3側のイベント通知機能を使おう
s3.Bucket.AddNotification
を使うlambda.Function.addEventSource
はS3バケットを新規作成する場合にしか対応してない
はじめに
今回やりたいことはこんなイメージ
S3のイベントドリブンでLambda関数を実行するパターンは以下の2パターンが考えられるかと思います。
- S3のイベント通知を使う
- Lambdaにイベントソースを追加する
僕は後者の『Lambdaにイベントソースを追加する』でいけるだろ〜と思ってやってみました。
Lambdaにイベントソースを追加するにはこの S3EventSource
クラスを使用します。
lambda.Function.addEventSource
でハマった
早速サンプルコードを真似して書いてみるとこんなエラーが。
型 'IBucket' の引数を型 'Bucket' のパラメーターに割り当てることはできません。
型 'IBucket' には 型 'Bucket' からの次のプロパティがありません: autoCreatePolicy, lifecycleRules, metrics, cors、32 など。
どうやらS3EventSourceで指定するバケットの型は Bucket
じゃないとダメらしい。
既存バケットを取得する方法としては、s3.Bucketの fromBucketArn()
、fromBucketAttributes()
、 fromBucketName()
があるのですが、これらの戻り値の型はどれも IBucket
なんです。。。
Google先生と睨めっこしてたらこんなissueがありました。
S3EventSource should take IBucket instead of Bucket #4323 - https://github.com/aws/aws-cdk/issues/4323
どうやら既存バケットを使う場合は s3.Bucket.AddNotification
を使うのが正解っぽい。
【解決方法】 s3.Bucket.AddNotification
ということで、既存バケットのイベントドリブンでLambda関数を実行したい場合は s3.Bucket.AddNotification
を使いましょう。
sumple.ts
// Lambda Function
const target_function = new Function(this, "sumpleFunc", {
code: new AssetCode("resources"),
handler: "index.handler",
runtime: Runtime.NODEJS_16_X,
functionName: "sumple_function",
timeout: Duration.seconds(60)
});
// 既存のS3バケットを取得
const existing_bucket = Bucket.fromBucketArn(
this,
'sumple-bucket-20220630-becominn',
'arn:aws:s3:::sumple-bucket-20220630-becominn'
)
// S3Notificationを設定
existing_bucket.addEventNotification(
EventType.OBJECT_CREATED_PUT,
new LambdaDestination(target_function)
)
サンプルのソースコードも置いておきます。
最後に
今回の解決方法はどちらかといえば妥協案のようなものですが、やりたいことは達成出来ました。
私は最近CDKを触り始めた初心者なので、今回のように型でハマることが多いですね。(ただ型があるのは嬉しい)
本記事がどなたかのお役に立てれば幸いです。
以上、べこみんでした。