CarlR
CarlR

Reputation: 1768

How to get the Arn of a lambda function's execution role in AWS CDK

My use case is:

I want to execute a lambda function for the PUT event of an existing S3 bucket.

The problem is that you in CloudFormation or CDK you cannot add notifications for an existing bucket, only for buckets that are created.

To get around this I am trying to use a custom resource that adds the Lambda function to the PutNotification. I have this working fine in CloudFormation but I am trying to use CDK now to do something similar.

To simulate what I have in CloudFormation I need to add a bucket policy to the existing bucket granting permission to the action s3:PutBucketNotification to the lambda execution role principal.

In CloudFormation I do this like this:

NotificationBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref BucketName
      PolicyDocument:
        Statement:
          - Effect: "Allow"
            Action:
            - 's3:PutBucketNotification'
            Resource: !Sub "arn:aws:s3:::${BucketName}"
            Principal:
              AWS: !GetAtt LambdaExecutionRole.Arn

I am attempting to create the bucket policy and add the statement to it in CDK but I need the Arn of the Lambda Function's Arn

const bucket = Bucket.fromBucketName(this, "Bucket", "my-bucket-name");

const bucketConfigurationFunction = new lambda.SingletonFunction(this, "bucketConfigurationFunction ", {
      runtime: lambda.Runtime.NODEJS_8_10,
      code: lambda.Code.asset('lambda/bucket-configuration'),
      handler: 'lambda_function.handler',
      timeout: cdk.Duration.seconds(300),
      uuid: '72561a5f-e772-4365-b3d1-f59e8ddc60b1'
    }) 

const bucketPolicy = new BucketPolicy(this, "TargetBucketPolicy", {
      bucket: bucket
    })


const bucketPolicyStatement = new PolicyStatement()
bucketPolicyStatement.addActions("s3:PutBucketNotification");
//Need to put the execution role arn here but role is undefined
bucketPolicyStatement.addArnPrincipal(bucketConfigurationFunction.role.roleArn)

I have read the CDK creates a lambda function execution role automatically however when I try to access the role Arn to add it as the principal in the policy statement, it is undefined.

Am I doing this totally the wrong way?

Upvotes: 1

Views: 4879

Answers (1)

Lee
Lee

Reputation: 2242

Because TypeScript is quite strict on checking optional variables and the role is generated at runtime, you need to box it using and if but that's still fine. For example this works:

    const bucketPolicyStatement = new iam.PolicyStatement()
    bucketPolicyStatement.addActions("s3:PutBucketNotification");

    if (bucketConfigurationFunction.role) {
      bucketPolicyStatement.addArnPrincipal(bucketConfigurationFunction.role.roleArn)
    }

    const bucketPolicy = new s3.BucketPolicy(this, "TargetBucketPolicy", {
      bucket: bucket,
    })

    bucketPolicy.document.addStatements(bucketPolicyStatement);

Upvotes: 0

Related Questions