awslabs / aws-solutions-constructs

The AWS Solutions Constructs Library is an open-source extension of the AWS Cloud Development Kit (AWS CDK) that provides multi-service, well-architected patterns for quickly defining solutions
https://docs.aws.amazon.com/solutions/latest/constructs/
Apache License 2.0
1.24k stars 249 forks source link

CloudFrontToS3: Stack fails deployment after cdk-lib version update #1206

Open tbelmega opened 1 month ago

tbelmega commented 1 month ago

I updated my aws-cdk library version and aws-solutions-constructs version to the latest (v2.158.0/v2.70). After the update, my stack failed to deploy. CloudFormation responds with

“Invalid request provided: AWS::CloudFront::Distribution: Cannot use both Origin Access Control and Origin Access Identity on an origin (Service: CloudFront, Status Code: 400, Request ID: xxx)” (RequestToken: yyy, HandlerErrorCode: InvalidRequest)

Reproduction Steps

Reference in solution code

    new CloudFrontToS3(scope, 'CloudFront',
      {
        existingBucketObj: bucket,
        insertHttpSecurityHeaders: false,
        cloudFrontDistributionProps: {
          defaultBehavior: {
            origin: new S3Origin(this.s3BucketInterface),
          }
        } as DistributionProps
      }
    );

This code worked with aws-cdk-lib prior to 2.148.0, and throws an error at deployment time since I upgraded to 2.158.0.

The fix for my solution is to change origin: new S3Origin(this.s3BucketInterface), to origin: S3BucketOrigin.withOriginAccessControl(this.s3BucketInterface),

Error Log

Invalid request provided: AWS::CloudFront::Distribution: Cannot use both Origin Access Control and Origin Access Identity on an origin (Service: CloudFront, Status Code: 400, Request ID: xxx)" (RequestToken: yyy, HandlerErrorCode: InvalidRequest)

Environment

Other


This is :bug: Bug Report

biffgaut commented 1 month ago

Here's what's going on - up through version 2.47.0 the aws-cloudfront-s3 would create and deploy an OAI between the distribution and the origin. When a client created an S3Origin and sent it through the cloudFrontDistributionProps, it would overwrite the S3Origin in the props sent to the Distribution constructor. Since an S3Origin was an object but not a construct, there were no negative repercussions from both the client and Solutions Construct creating one.

When the OAC was introduced, it became the recommended technology and regions launched after December 2022 will not support OAI. The S3Origin class has been deprecated (did you catch me using "was" earlier?), and apps should be moving to OAC. With version 2.48.0, the aws-cloudfront-s3 construct switched to an OAC implementation. Clients that relied on the construct to create the origin were able migrate to OAC with little to no effort. The construct now sends an OAC to the Distribution constructor. Any S3Origin received from the client, such as in the code above, no longer overwrites the S3Origin created by the construct - it gets sent to the Distribution constructor alongside the OAC, and the result is the error above.

A simple solution is just to allow the consttruct to create the OAC:

    new CloudFrontToS3(scope, 'CloudFront',
      {
        existingBucketObj: bucket,
        insertHttpSecurityHeaders: false,
        cloudFrontDistributionProps: {
        } as DistributionProps
      }
    );

You can still set things like viewerProtocolPolicy or responseHeadersPolicy through the defaultBehavior in the Distribution props (although we'd recommend using CloudFrontToS3Props.responseHeadersPolicyProps and letting the Solutions Construct do the work).

We could perceive a use case where a client wanted very specialized behavior in the OAC, and needed to set specific OriginProps, although that doesn't seem to be an issue in the example above (which may be simplified). If customers have a need to set specific OriginProps, they can register that need here or in a new Issue and we can look at prioritizing it.