AWS CDKでは(というかCloudFormationでは)既存のS3 bucketのイベントへの購読を新たに追加することができない。が、SQS queueに既存のSNS topicを購読させることはできる。
ので、S3のobjectCreatedイベントが発生したらSNS topicにメッセージをpublishするようにあらかじめ設定しておけば、以下の順序でメッセージを伝達していくことで、AWS CDK (with CloudFormation)で作ったAWS Lambdaのトリガーを引くことが可能。
S3 => SNS topic => SQS subscription => Lambda
以下がSQS Subscription以降を作るAWS CDKのConstructの例。
import core = require("@aws-cdk/core");
import lambda = require("@aws-cdk/aws-lambda");
import s3 = require("@aws-cdk/aws-s3");
import sns = require("@aws-cdk/aws-sns");
import sqs = require("@aws-cdk/aws-sqs");
import { SqsEventSource } from "@aws-cdk/aws-lambda-event-sources";
import { SqsSubscription } from "@aws-cdk/aws-sns-subscriptions";
export class ExistingS3BucketAndSNSTopicToLambdaThroughSQS extends core.Construct {
constructor(scope: core.Construct, id: string) {
super(scope, id);
const bucket = s3.Bucket.fromBucketName(
this,
"ExistingS3Bucket",
"bucketName"
);
const handler = new lambda.Function(this, "lambda", {
runtime: lambda.Runtime.NODEJS_10_X,
code: lambda.Code.asset("lambda/dist"),
handler: "index.main",
timeout: core.Duration.seconds(30),
environment: {
BUCKET_NAME: bucket.bucketName
}
});
bucket.grantRead(handler);
const topic = sns.Topic.fromTopicArn(
this,
"ExistingSNSTopic",
`arn:${core.Aws.PARTITION}:sns:${core.Aws.REGION}:${core.Aws.ACCOUNT_ID}:existing-sns-topic`
);
const queue = new sqs.Queue(this, "queue");
topic.addSubscription(new SqsSubscription(queue));
handler.addEventSource(
new SqsEventSource(queue, {
batchSize: 1
})
);
}
}
AWS CDK v1.6.1 では動いたけどそれ以外のバージョンではもしかしたらAPI変わってるかも。
Gist: https://gist.github.com/katryo/ff3cf8b5e3f12823ad7bc2468db054cd
AWS CDKは流行ってほしい。みんなどんどん自分の作ったConstructを公開していってくれ。
CloudFormation直書きとかもう時間の無駄なので……。