Help us understand the problem. What is going on with this article?

AWS CDKから既存のLambdaトリガに既存のS3を設定する

IAMロールのポリシー設定権限が無い環境において、AWS CDKから既存のS3バケットNotificationに既存のLambdaを設定しようとしたら、このようなissueやらcfnリソースの依存性の循環やらで苦労したのでメモ。

解決のポイント

  • 依存性の循環回避にはカスタムリソースで対応
  • 既存LambdaにS3パーミッションを与えるにはローレベルなAPIlambda.CfnPermissionを使う
    • v1.18.0時点でこのようになっているため、lambda.Function.fromFunctionArn().addPermission()でパーミッション設定できない。warningすら出ず、何が悪いか気がつけないYO。
  • カスタムリソースにLambdaを実行するためのIAMロールを指定する
    • ロールを指定しないとCDK側でロールを作成するが、作成権限が無いためリソース生成に失敗。。。
    • ↑開発者にIAMポリシー変更できる強めの権限が与えられている環境であれば、この点は問題無し。

実装例

import iam = require('@aws-cdk/aws-iam');
import lambda = require('@aws-cdk/aws-lambda');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/core');
import cr = require('@aws-cdk/custom-resources');

export class S3NotificationStack extends cdk.Stack {
    constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
        super(scope, id, props);

        const bucketName = '{s3_bucket_name}';
        const functionArn = '{lambda_function_arn}';
        const lambdaRoleArn = '{iam_role_arn_for_execute_lambda}';

        // s3 bucket
        const bucket = s3.Bucket.fromBucketName(this, 'ExistingBucket', bucketName);

        // lambda function
        const fn = lambda.Function.fromFunctionArn(
            this,
            'ExistingFunction',
            functionArn);

        // avoid circular dependency.
        const cres = new cr.AwsCustomResource(this, 'S3NotificationResource', {
            role: iam.Role.fromRoleArn(this, 'LambdaRole',
                lambdaRoleArn),
            onCreate: {
                service: 'S3',
                action: 'putBucketNotificationConfiguration',
                parameters: {
                    Bucket: bucket.bucketName,
                    NotificationConfiguration: {
                        LambdaFunctionConfigurations: [
                            {
                                Events: ['s3:ObjectCreated:*'],
                                LambdaFunctionArn: fn.functionArn,
                                Filter: {
                                    Key: {
                                        FilterRules: [
                                            { Name: 'prefix', Value: 'hoge/' },
                                            { Name: 'suffix', Value: '.jpg' }]
                                    }
                                }
                            }
                        ]
                    }
                },
                physicalResourceId: 'S3NotificationCustomResource' + Date.now().toString()
            }
        });

        // avoid this.
        // https://github.com/aws/aws-cdk/blob/v1.18.0/packages/%40aws-cdk/aws-lambda/lib/function-base.ts#L189
        const perm = new lambda.CfnPermission(this, "AllowS3Invocation", {
            action: 'lambda:InvokeFunction',
            functionName: fn.functionName,
            principal: 's3.amazonaws.com',
            sourceArn: bucket.bucketArn
        });

        // for executing following order.
        // add permission to lambda -> set s3 notification
        cres.node.addDependency(perm);
    }
}

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away