Skip to content

Commit

Permalink
fix(cloudfront): requirement of domainNames prevents moving a domain …
Browse files Browse the repository at this point in the history
…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*
  • Loading branch information
Tietew authored Aug 21, 2024
1 parent 5387605 commit acdf7d3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 19 deletions.
10 changes: 10 additions & 0 deletions packages/aws-cdk-lib/aws-cloudfront/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ new cloudfront.Distribution(this, 'myDist', {
});
```

#### Moving an alternate domain name to a different distribution

When you try to add an alternate domain name to a distribution but the alternate domain name is already in use on a different distribution, you get a `CNAMEAlreadyExists` error (One or more of the CNAMEs you provided are already associated with a different resource).

In that case, you might want to move the existing alternate domain name from one distribution (the source distribution) to another (the target distribution). The following steps are an overview of the process. For more information, see [Moving an alternate domain name to a different distribution](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/alternate-domain-names-move.html).

1. Deploy the stack with the target distribution. The `certificate` property must be specified but the `domainNames` should be absent.
2. Move the alternate domain name by running CloudFront `associate-alias` command. For the example and preconditions, see the AWS documentation above.
3. Specify the `domainNames` property with the alternative domain name, then deploy the stack again to resolve the drift at the alternative domain name.

#### Cross Region Certificates

> **This feature is currently experimental**
Expand Down
9 changes: 4 additions & 5 deletions packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ export interface DistributionProps {
*
* If you want to use your own domain name, such as www.example.com, instead of the cloudfront.net domain name,
* you can add an alternate domain name to your distribution. If you attach a certificate to the distribution,
* you must add (at least one of) the domain names of the certificate to this list.
* you should add (at least one of) the domain names of the certificate to this list.
*
* When you want to move a domain name between distributions, you can associate a certificate without specifying any domain names.
* For more information, see the _Moving an alternate domain name to a different distribution_ section in the README.
*
* @default - The distribution will only support the default generated name (e.g., d111111abcdef8.cloudfront.net)
*/
Expand Down Expand Up @@ -318,10 +321,6 @@ export class Distribution extends Resource implements IDistribution {
if (!Token.isUnresolved(certificateRegion) && certificateRegion !== 'us-east-1') {
throw new Error(`Distribution certificates must be in the us-east-1 region and the certificate you provided is in ${certificateRegion}.`);
}

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

const originId = this.addOrigin(props.defaultBehavior.origin);
Expand Down
27 changes: 13 additions & 14 deletions packages/aws-cdk-lib/aws-cloudfront/test/distribution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,23 +457,22 @@ describe('certificates', () => {
}).toThrow(/Distribution certificates must be in the us-east-1 region and the certificate you provided is in eu-west-1./);
});

test('adding a certificate without a domain name throws', () => {
test('adding a certificate without a domain name', () => {
const certificate = acm.Certificate.fromCertificateArn(stack, 'Cert', 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012');

expect(() => {
new Distribution(stack, 'Dist1', {
defaultBehavior: { origin: defaultOrigin() },
certificate,
});
}).toThrow(/Must specify at least one domain name/);
new Distribution(stack, 'Dist1', {
defaultBehavior: { origin: defaultOrigin() },
certificate,
});

expect(() => {
new Distribution(stack, 'Dist2', {
defaultBehavior: { origin: defaultOrigin() },
domainNames: [],
certificate,
});
}).toThrow(/Must specify at least one domain name/);
Template.fromStack(stack).hasResourceProperties('AWS::CloudFront::Distribution', {
DistributionConfig: {
Aliases: Match.absent(),
ViewerCertificate: {
AcmCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012',
},
},
});
});

test('use the TLSv1.2_2021 security policy by default', () => {
Expand Down

0 comments on commit acdf7d3

Please sign in to comment.