Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws-cloudfront: cdk incorrectly prevents attaching certificate when no aliases are given #29960

Labels
@aws-cdk/aws-cloudfront Related to Amazon CloudFront bug This issue is a bug. effort/medium Medium work item – several days of effort p3

Comments

@lexhl
Copy link

lexhl commented Apr 25, 2024

Describe the bug

Hi, I am trying to follow the instructions on how to move an alias from an existing alias from one CloudFront distribution to another. The instructions says that I need to set up the target distribution with a certificate that includes the alternative domain name that I want to move: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move-create-target

However when I try to set up the distribution with the certificate but without the alternative domain names (as directed in the instructions) I run into an error 'Must specify at least one domain name to use a certificate with a distribution' generated I think from this like of code within CDK:

aws-cdk/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts
Line 323 in 6fdc458

 throw new Error('Must specify at least one domain name to use a certificate with a distribution'); 

It seems that CDK prevents me from adding a certificate unless I have a domain name; but that means I cannot follow the process for moving an alias from an old distribution to a new one. I can create a distribution with a certificate and no alias if I use the aws web console to do it; so I think CDK is wrong with this validation.

Expected Behavior

CDK should allow me to create a cloudfront distribution that has an ACM certificate attached but no aliases

Current Behavior

CDK raises an error message 'Must specify at least one domain name to use a certificate with a distribution' when I try to create a cloudfront distribution that has an ACM certificate attached but no aliases

Reproduction Steps

       distribution = cloudfront.Distribution(
            self,
            "Distribution",
            domain_names=[],
            default_behavior=cloudfront.BehaviorOptions(
                origin=origins.HttpOrigin(
                    dns_name,
                    protocol_policy=cloudfront.OriginProtocolPolicy.HTTPS_ONLY,
                    origin_ssl_protocols=[
                        cloudfront.OriginSslPolicy.TLS_V1_1,
                        cloudfront.OriginSslPolicy.TLS_V1_2,
                    ],
                    read_timeout=Duration.seconds(60),
                ),
                viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                origin_request_policy=cloudfront.OriginRequestPolicy.ALL_VIEWER,
                cache_policy=cache_policy,
                allowed_methods=cloudfront.AllowedMethods.ALLOW_ALL,
                compress=True,
            ),
            price_class=cloudfront.PriceClass.PRICE_CLASS_200,
            enabled=True,
            log_includes_cookies=False,
            log_bucket=logging_bucket,
            enable_logging=True,
            web_acl_id=waf_acl_arn,
            ssl_support_method=cloudfront.SSLMethod.SNI,
            certificate=my_certificate,
            minimum_protocol_version=cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
        )

Possible Solution

Remove the spurious validation check:

      if ((props.domainNames ?? []).length === 0) {
        throw new Error('Must specify at least one domain name to use a certificate with a distribution');
      }

Additional Information/Context

No response

CDK CLI Version

2.137.0 (build bb90b4c)

Framework Version

No response

Node.js Version

v21.7.1

OS

Mac OS

Language

Python

Language Version

Python 3.11

Other information

No response

@lexhl lexhl added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 25, 2024
@github-actions github-actions bot added the @aws-cdk/aws-cloudfront Related to Amazon CloudFront label Apr 25, 2024
@lexhl
Copy link
Author

lexhl commented Apr 25, 2024

I believe as a work-around it is possible to proceed by using the escape hatches to manipulate the CloudFormation output:

        cfn_distribution: cloudfront.CfnDistribution = distribution.node.default_child
        cfn_distribution.add_property_override(
            "DistributionConfig.ViewerCertificate",
            {
                "AcmCertificateArn": my_certificate.certificate_arn,
                "SslSupportMethod": "sni-only",
                "MinimumProtocolVersion": "TLSv1.2_2021",
            },
        )

@ashishdhingra
Copy link
Contributor

@lexhl Good afternoon. Per link https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move-create-target that you shared, it specifies to Get an SSL/TLS certificate that includes the alternate domain name that you are moving.. However, you are trying to set up the distribution with the certificate but without the alternative domain names, which is not what instructions mention. Please let me know if I'm missing anything.

Thanks,
Ashish

@ashishdhingra ashishdhingra added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Apr 25, 2024
@lexhl
Copy link
Author

lexhl commented Apr 26, 2024

@ashishdhingra

@lexhl Good afternoon. Per link https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move-create-target that you shared, it specifies to Get an SSL/TLS certificate that includes the alternate domain name that you are moving.. However, you are trying to set up the distribution with the certificate but without the alternative domain names, which is not what instructions mention. Please let me know if I'm missing anything.

Hi, the relevant instructions as per the article are as pasted below. You can see that you are required to first setup the distribution with the certificate but without the alias.

The second step is to run the associate-alias command, which moves the alias. This command is only allowed to be run if you have already created a target distribution that has the correct certificate attached but does not have the alias already associated with it. This is the point of the CloudFront associate-alias command.

This all works fine if done via the boto3 APIs or the web console. Only CDK blocks it -because CDK wrongly does not allow me to attach a certificate to a distribution that has no alias.

If you attempt to create a distribution that has the same alias as an existing distribution then CloudFront will prevent that. Hence why the associate-alias command exists to allow for zero downtime migration of aliases from one distribution to another.

  1. Get an SSL/TLS certificate that includes the alternate domain name that you are moving. If you don’t have one, you can request one from AWS Certificate Manager (ACM), or get one from another certificate authority (CA) and import it into ACM. Make sure that you request or import the certificate in the US East (N. Virginia) (us-east-1) Region.
  2. If you haven’t created the target distribution, create one now. As part of creating the target distribution, associate your certificate (from the previous step) with the distribution. For more information, see Creating a distribution.
  3. If you already have a target distribution, associate your certificate (from the previous step) with the target distribution. For more information, see Updating a distribution.
  4. Create a DNS TXT record that associates the alternate domain name with the distribution domain name of the target distribution. Create your TXT record with an underscore (_) in front of the alternate domain name. The following shows an example TXT record in DNS:
  5. _www.example.com TXT d111111abcdef8.cloudfront.net
  6. CloudFront uses this TXT record to validate your ownership of the alternate domain name.

.... and ...

  1. Use the AWS CLI to run the CloudFront associate-alias command, as shown in the following example. Replace www.example.com with the alternate domain name, and EDFDVBD6EXAMPLE with the target distribution ID. Run this command using credentials that are in the same AWS account as the target distribution. Note the following restrictions for using this command:

    • You must have cloudfront:AssociateAlias and cloudfront:UpdateDistribution permissions on the target distribution.
    • If the source and target distributions are in the same AWS account, you must have cloudfront:UpdateDistribution permission on the source distribution.
    • If the source and target distributions are in different AWS accounts, the source distribution must be disabled.
    • The target distribution must be set up as described in Set up the target distribution.
    aws cloudfront associate-alias --alias www.example.com --target-distribution-id EDFDVBD6EXAMPLE
    

    This command updates both distributions by removing the alternate domain name from the source distribution and adding it to the target distribution.

  2. After the target distribution is fully deployed, update your DNS configuration to point the alternate domain name’s DNS record to the distribution domain name of the target distribution.

@lexhl
Copy link
Author

lexhl commented Apr 26, 2024

Hi @ashishdhingra I have had confirmation from AWS premium support that they have reproduced the issue and they also suggested a similar workaround that I suggested above of using the L1 constructs instead (which does work). However it would be nice if the L2 construct just allowed this use case as it is an important use case sometimes.

Quote from AWS support:

I was also facing the same error-> "Must specify at least one domain name to use a certificate with a distribution
at new Distribution" [1] [2]
This is due to the CDK limitation.

A possible workaround to resolve this issue could be using L1 Constructs. 
I have tested the below code and it is working fine.

[code showing use of L1 Constructs matching my L2 sample]

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Apr 26, 2024
@ashishdhingra ashishdhingra added effort/medium Medium work item – several days of effort p3 labels Jul 31, 2024
@mergify mergify bot closed this as completed in #31001 Aug 21, 2024
@mergify mergify bot closed this as completed in acdf7d3 Aug 21, 2024
Copy link

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

Copy link

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 21, 2024
GavinZZ pushed a commit that referenced this issue Aug 22, 2024
…name between distributions (#31001)

### Issue # (if applicable)

Closes #29960.

### Reason for this change

When I want to move a domain name from a distribution to another distribution,
I must create a distribution with a certificate associated but no domain names.

### Description of changes

Re-submit of previous #29329.
Removed the validation that `domainNames` must not be blank when a certificate is associated.

### Description of how you validated changes

Updated a unit test to allow absent domainNames when a certificate is associated.

See AWS Documentation for details: Using custom URLs by adding alternate domain names (CNAMEs) > Moving an alternate domain name to a different distribution
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
GavinZZ pushed a commit that referenced this issue Aug 23, 2024
…name between distributions (#31001)

### Issue # (if applicable)

Closes #29960.

### Reason for this change

When I want to move a domain name from a distribution to another distribution,
I must create a distribution with a certificate associated but no domain names.

### Description of changes

Re-submit of previous #29329.
Removed the validation that `domainNames` must not be blank when a certificate is associated.

### Description of how you validated changes

Updated a unit test to allow absent domainNames when a certificate is associated.

See AWS Documentation for details: Using custom URLs by adding alternate domain names (CNAMEs) > Moving an alternate domain name to a different distribution
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.