ssennettau / CloudFrontRedirector-Construct

CDK Construct to simplify using CloudFront to redirect entire domains or back-half stubs
MIT License
0 stars 0 forks source link

Replacing custom paths results in CFN update error #2

Open ssennettau opened 7 months ago

ssennettau commented 7 months ago

🤔 Expected Behaviour

After creating a CDK Stack using the CloudFrontRedirector Construct which includes customPaths, I should be able to modify the contents to different paths, or new paths, and to have it take effect without any issue.

💥 Actual Behaviour

When custom paths are modified, it triggers an update of the resource. The KeyValueStore returns an error

x:xx:xx xM | UPDATE_FAILED        | AWS::CloudFront::KeyValueStore                  | RedirectionForWebsiteRedirectMapA33E06EB
CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename [StackName][ResourceName]RedirectMap[UniqueID] and update the stack again.

🛠️ Steps to Reproduce

  1. Create a new CDK Stack
  2. Add the following resource
    const redirect = new RedirectionSite(this, "RedirectForWebsite", {
      targetUrl: "https://github.com/ssennettau/CloudFrontRedirector-Construct",
      pathRedirects: [
        {
          path: "/repo",
          destination: "https://github.com/ssennettau/CloudFrontRedirector"
        }
      ]
    });
  3. Deploy the CDK stack
  4. Modify a customPath
    const redirect = new RedirectionSite(this, "RedirectForWebsite", {
      targetUrl: "https://github.com/ssennettau/CloudFrontRedirector-Construct",
      pathRedirects: [
        {
          path: "/repository",
          destination: "https://github.com/ssennettau/CloudFrontRedirector-Construct"
        }
      ]
    });
  5. Attempt to deploy the CDK stack again

Error as described in Actual Behaviour should be present.

💡 Workaround (if known)

Renaming the resource is an effective, though inefficient way to bypass this bug.

const redirect = new RedirectionSite(this, "RedirectForWebsite", { ... });

// ...renamed...

const redirect = new RedirectionSite(this, "RedirectForWebsite-2", { ... });

This also triggers a full deletion and re-creation of the whole underlying construct, including the CloudFront Distribution, and any Route 53 records. They're all re-created, but this can take over 15 minutes for the deployment to complete.

ssennettau commented 7 months ago

Issue is with how the underlying cloudfront.KeyValueStore works.

The contents of the KeyValueStore are derived from an S3 Object, and aren't stored in the resource itself. Since the underlying L2 construct doesn't support in-line declarations aws-cdk issue #29204, the adopted workaround for this construct creates a temporary file to be uploaded to S3 using the cloudfront.ImportSource.fromAsset method.

This behaviour confirmed in a blog post found, AWS CDK now supports L2 Construct for CloudFront KeyValueStore (title translated).

This might be solved by keeping the file in a static bucket location, which can be modified with the new contents, but it should probably be fixed in the CDK Construct itself. Will investigate further when time permits.

ssennettau commented 7 months ago

Implemented workaround patch (PR #3) for the issue by the construct automatically randomizing the name of the KeyValueStore each time. Solves the user experience issue, but leaves the problem that it updates the underlying CloudFront Distribution each time, taking extra time to deploy.

Leaving open for additional work and reference.