如何在AWS CDK中获得Lambda函数执行角色的Arn

时间:2019-10-04 17:13:57

标签: aws-lambda aws-cdk

我的用例是:

我想为现有S3存储桶的PUT事件执行一个lambda函数。

问题是您在CloudFormation或CDK中无法为现有存储桶添加通知,而只能为创建的存储桶添加通知。

要解决此问题,我尝试使用将Lambda函数添加到PutNotification的自定义资源。我在CloudFormation中的工作情况还不错,但现在尝试使用CDK做类似的事情。

要模拟我在CloudFormation中拥有的内容,我需要在现有存储桶中添加存储桶策略,以将操作s3:PutBucketNotification的权限授予lambda执行角色主体。

在CloudFormation中,我这样做如下:

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

我试图创建存储桶策略并将其添加到CDK中,但是我需要Lambda函数的Arn的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)

我已经阅读过CDK自动创建一个lambda函数执行角色,但是当我尝试访问角色Arn并将其添加为策略语句中的主体时,它是未定义的。

我这样做完全错误吗?

1 个答案:

答案 0 :(得分:0)

由于TypeScript在检查可选变量方面非常严格,并且role是在运行时生成的,因此您需要使用和if将其装箱,但这还是可以的。例如,这有效:

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