Cdk.aws_s3_deployment.BucketDeployment: Fails On Destroy Because Of Missing IAM Permissions

by ADMIN 92 views

Introduction

When using the cdk.aws_s3_deployment.BucketDeployment construct in a CloudFront distribution, you may encounter an error on destroy due to missing IAM permissions. This article will guide you through the issue, its reproduction steps, and a possible solution to resolve the problem.

Describe the bug

When using the BucketDeployment construct in a CloudFront distribution, the following code snippet is used:

const deployment = new s3deploy.BucketDeployment(this, 'myDeployment', {
    sources: [s3deploy.Source.asset('myPath')],
    destinationBucket: myBucket,
    distribution: myDistribution,
    retainOnDelete: false
});

With this type of origin: S3BucketOrigin.withOriginAccessControl(mybucket), you get the following error on a CDK destroy:

Regression Issue

  • [ ] Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

Successful distribution removal

Current Behavior

The following error occurs:

Received response status [FAILED] from custom resource. Message returned: Waiter InvalidationCompleted failed: An error occurred (AccessDenied): User: arn:aws:sts::123456789012:assumed-role/DevStage-CloudfrontStack-CustomCDKBucketDeployment8-WcZbgrfLNFSa/DevStage-CloudfrontStack-CustomCDKBucketDeployment-timMc5RFviZB is not authorized to perform: cloudfront:GetInvalidation on resource: arn:aws:cloudfront::123456789012:distribution/XXXXXXXXXXXX because no identity-based policy allows the cloudfront:GetInvalidation action (RequestId: xxxxxxxxxxxxxxxf)

Reproduction Steps

  1. Create an S3 deployment using the BucketDeployment construct:
const deployment = new s3deploy.BucketDeployment(this, 'myDeployment', {
    sources: [s3deploy.Source.asset('myPath')],
    destinationBucket: myBucket,
    distribution: myDistribution,
    retainOnDelete: false
});
  1. Create a distribution using S3BucketOrigin.withOriginAccessControl(mybucket):
S3BucketOrigin.withOriginAccessControl(mybucket)
  1. Deploy the distribution and try to destroy it.

Possible Solution

The addition of missing permissions like this fixes the issue:

deployment.handlerRole.addToPrincipalPolicy(new cdk.aws_iam.PolicyStatement({
    effect: cdk.aws_iam.Effect.ALLOW,
    actions: [
        'cloudfront:GetInvalidation',
        'cloudfront:CreateInvalidation'
    ],
    resources: ['*']
}));

Additional Information/Context

No response

CDK CLI Version

2.1003.0 (build b242c23)

Framework Version

No response

Node.js Version

v22.12.0

OS

Ubuntu 22.04.5 LTS (WSL)

Language

TypeScript

Language Version

No response

Other information

No response

Q&A

Q: What is the issue with cdk.aws_s3_deployment.BucketDeployment when using it in a CloudFront distribution?

A: The issue is that the BucketDeployment construct fails on destroy due to missing IAM permissions.

Q: What is the error message I receive when trying to destroy the distribution?

A: The error message is:

Received response status [FAILED] from custom resource. Message returned: Waiter InvalidationCompleted failed: An error occurred (AccessDenied): User: arn:aws:sts::123456789012:assumed-role/DevStage-CloudfrontStack-CustomCDKBucketDeployment8-WcZbgrfLNFSa/DevStage-CloudfrontStack-CustomCDKBucketDeployment-timMc5RFviZB is not authorized to perform: cloudfront:GetInvalidation on resource: arn:aws:cloudfront::123456789012:distribution/XXXXXXXXXXXX because no identity-based policy allows the cloudfront:GetInvalidation action (RequestId: xxxxxxxxxxxxxxxf)

Q: What is the cause of this error?

A: The cause of this error is that the BucketDeployment construct is missing the necessary IAM permissions to perform the cloudfront:GetInvalidation action.

Q: How can I resolve this issue?

A: To resolve this issue, you need to add the missing IAM permissions to the BucketDeployment construct. You can do this by adding the following code:

deployment.handlerRole.addToPrincipalPolicy(new cdk.aws_iam.PolicyStatement({
    effect: cdk.aws_iam.Effect.ALLOW,
    actions: [
        'cloudfront:GetInvalidation',
        'cloudfront:CreateInvalidation'
    ],
    resources: ['*']
}));

Q: What are the necessary IAM permissions for the BucketDeployment construct?

A: The necessary IAM permissions for the BucketDeployment construct are:

  • cloudfront:GetInvalidation
  • cloudfront:CreateInvalidation

Q: Why do I need to add these IAM permissions?

A: You need to add these IAM permissions because the BucketDeployment construct requires them to perform the necessary actions on the CloudFront distribution.

Q: Can I add these IAM permissions to the BucketDeployment construct in a different way?

A: Yes, you can add these IAM permissions to the BucketDeployment construct in a different way. However, the above code snippet is the recommended way to do it.

Q: What are the benefits of adding these IAM permissions to the BucketDeployment construct?

A: The benefits of adding these IAM permissions to the BucketDeployment construct are:

  • You can successfully destroy the CloudFront distribution.
  • You can avoid the error message that is caused by missing IAM permissions.

Q: Can I use the BucketDeployment construct without adding these IAM permissions?

A: No, you cannot use the BucketDeployment construct without adding these IAM permissions. The BucketDeployment construct requires these IAM permissions to perform the necessary actions on the CloudFront distribution.