Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@shtmr

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

More than 1 year has passed since last update.

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);
    }
}

参考

1
Help us understand the problem. What is going on with this article?
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
shtmr

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?