Skip to content

Commit deeb2ad

Browse files
authored
feat(cognito): new cloudFrontEndpoint method for user pool domain without custom resource (#31402)
### Issue # (if applicable) Closes #31342. ### Reason for this change `UserPoolDomain` creates a custom resource to get CloudFront endpoint. However, CFn exposes the attribute natively now (see the issue). No custom resource is better if it is not needed. ### Description of changes I propose a new method `cloudFrontEndpoint` without a custom resource. Three ways were originally considered. This method was chosen as it was the most reasonable of all. #### 1. Create a new method This is the method submitted in this PR. #### 2. Rewrite an existing method directly This causes destructive changes. Custom resources are not directly used in the user's application. However, this change will result in resource deletion in the user's CDK stack. This causes confusion for users and should be avoided. Also, the existing integ tests that use the method will fail because the changes are considered as destructive changes. ``` Tests: 1 failed, 1 total Failed: /aws-cdk/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js !!! This test contains destructive changes !!! Stack: integ-user-pool-domain-cfdist - Resource: UserPoolDomainCloudFrontDomainNameE213E594 - Impact: WILL_DESTROY Stack: integ-user-pool-domain-cfdist - Resource: UserPoolDomainCloudFrontDomainNameCustomResourcePolicy7DE54188 - Impact: WILL_DESTROY Stack: integ-user-pool-domain-cfdist - Resource: AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2 - Impact: WILL_DESTROY Stack: integ-user-pool-domain-cfdist - Resource: AWS679f53fac002430cb0da5b7982bd22872D164C4C - Impact: WILL_DESTROY !!! If these destructive changes are necessary, please indicate this on the PR !!! Error: Some changes were destructive! at main (/aws-cdk/packages/@aws-cdk/integ-runner/lib/cli.js:183:15) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. ``` #### 3. Rewrite an existing method with a feature flag An alternative to way 2, but a feature flag was avoided in this case as it leads to complexity. The [design guidelines](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md#dealing-with-breaking-behavior-changes) also recommend a new method. ### Additional information I avoided the feature flag in this PR, but there are situations where there are constructs that use an existing method, but cannot provide a new method for the constructs because it is used by a method implemented in the interface. https://github.com/go-to-k/aws-cdk/blob/fcbdc769e681f1f915cdc8cd7aa3a565d807884d/packages/aws-cdk-lib/aws-route53-targets/lib/userpool-domain.ts#L14 I will make changes to those cases using a feature flag in a separate PR. #31403 ### Description of how you validated changes Both unit and integ tests. ### 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*
1 parent af5345e commit deeb2ad

File tree

13 files changed

+105
-19
lines changed

13 files changed

+105
-19
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/asset.746da84b10e215c552e68b6d2061024e4429f0386f43a35ef5e4d2940655692e/index.js

-1
This file was deleted.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/asset.9e8936ba1db43e0919ba2fc8265d50686eeaca82830c471ff8b7b0672c5970ec/index.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/cdk.out

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/integ-user-pool-domain-cfdist.assets.json

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/integ-user-pool-domain-cfdist.template.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
"S3Bucket": {
149149
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
150150
},
151-
"S3Key": "746da84b10e215c552e68b6d2061024e4429f0386f43a35ef5e4d2940655692e.zip"
151+
"S3Key": "9e8936ba1db43e0919ba2fc8265d50686eeaca82830c471ff8b7b0672c5970ec.zip"
152152
},
153153
"Handler": "index.handler",
154154
"Role": {
@@ -186,6 +186,14 @@
186186
"DomainDescription.CloudFrontDistribution"
187187
]
188188
}
189+
},
190+
"CloudFrontEndpoint": {
191+
"Value": {
192+
"Fn::GetAtt": [
193+
"UserPoolDomainD0EA232A",
194+
"CloudFrontDistribution"
195+
]
196+
}
189197
}
190198
},
191199
"Mappings": {

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/integ.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/manifest.json

+18-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.js.snapshot/tree.json

+9-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-domain-cfdist.ts

+4
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ new CfnOutput(stack, 'Domain', {
2626
new CfnOutput(stack, 'CloudFrontDomainName', {
2727
value: domain.cloudFrontDomainName,
2828
});
29+
30+
new CfnOutput(stack, 'CloudFrontEndpoint', {
31+
value: domain.cloudFrontEndpoint,
32+
});

packages/aws-cdk-lib/aws-cognito/README.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw
1919
- [Table of Contents](#table-of-contents)
2020
- [User Pools](#user-pools)
2121
- [Sign Up](#sign-up)
22+
- [Code Verification](#code-verification)
23+
- [Link Verification](#link-verification)
2224
- [Sign In](#sign-in)
2325
- [Attributes](#attributes)
2426
- [Attribute verification](#attribute-verification)
@@ -925,7 +927,6 @@ const fullAccessClient = pool.addClient('full-access-client', {
925927
});
926928
```
927929

928-
929930
### Domains
930931

931932
After setting up an [app client](#app-clients), the address for the user pool's sign-up and sign-in webpages can be
@@ -994,6 +995,21 @@ Existing domains can be imported into CDK apps using `UserPoolDomain.fromDomainN
994995
const myUserPoolDomain = cognito.UserPoolDomain.fromDomainName(this, 'my-user-pool-domain', 'domain-name');
995996
```
996997

998+
To get the domain name of the CloudFront distribution associated with the user pool domain, use `cloudFrontEndpoint` method.
999+
1000+
```ts
1001+
const userpool = new cognito.UserPool(this, 'UserPool');
1002+
const domain = userpool.addDomain('Domain', {
1003+
cognitoDomain: {
1004+
domainPrefix: 'my-awesome-app',
1005+
},
1006+
});
1007+
1008+
new CfnOutput(this, 'CloudFrontEndpoint', {
1009+
value: domain.cloudFrontEndpoint,
1010+
});
1011+
```
1012+
9971013
### Deletion protection
9981014

9991015
Deletion protection can be enabled on a user pool to prevent accidental deletion:

packages/aws-cdk-lib/aws-cognito/lib/user-pool-domain.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export class UserPoolDomain extends Resource implements IUserPoolDomain {
9696
private isCognitoDomain: boolean;
9797

9898
private cloudFrontCustomResource?: AwsCustomResource;
99+
private readonly resource: CfnUserPoolDomain;
99100

100101
constructor(scope: Construct, id: string, props: UserPoolDomainProps) {
101102
super(scope, id);
@@ -114,18 +115,29 @@ export class UserPoolDomain extends Resource implements IUserPoolDomain {
114115
this.isCognitoDomain = !!props.cognitoDomain;
115116

116117
const domainName = props.cognitoDomain?.domainPrefix || props.customDomain?.domainName!;
117-
const resource = new CfnUserPoolDomain(this, 'Resource', {
118+
this.resource = new CfnUserPoolDomain(this, 'Resource', {
118119
userPoolId: props.userPool.userPoolId,
119120
domain: domainName,
120121
customDomainConfig: props.customDomain ? { certificateArn: props.customDomain.certificate.certificateArn } : undefined,
121122
});
122123

123-
this.domainName = resource.ref;
124+
this.domainName = this.resource.ref;
124125
}
125126

126127
/**
127128
* The domain name of the CloudFront distribution associated with the user pool domain.
128129
*/
130+
public get cloudFrontEndpoint(): string {
131+
return this.resource.getAtt('CloudFrontDistribution').toString();
132+
}
133+
134+
/**
135+
* The domain name of the CloudFront distribution associated with the user pool domain.
136+
*
137+
* This method creates a custom resource internally to get the CloudFront domain name.
138+
*
139+
* @deprecated use `cloudFrontEndpoint` method instead.
140+
*/
129141
public get cloudFrontDomainName(): string {
130142
if (!this.cloudFrontCustomResource) {
131143
const sdkCall: AwsSdkCall = {

packages/aws-cdk-lib/aws-cognito/test/user-pool-domain.test.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { testDeprecated } from '@aws-cdk/cdk-build-tools';
12
import { Template } from '../../assertions';
23
import { Certificate } from '../../aws-certificatemanager';
34
import { CfnParameter, Stack } from '../../core';
@@ -103,7 +104,7 @@ describe('User Pool Domain', () => {
103104
})).not.toThrow();
104105
});
105106

106-
test('custom resource is added when cloudFrontDomainName property is used', () => {
107+
testDeprecated('custom resource is added when cloudFrontDomainName property is used', () => {
107108
// GIVEN
108109
const stack = new Stack();
109110
const pool = new UserPool(stack, 'Pool');
@@ -137,7 +138,7 @@ describe('User Pool Domain', () => {
137138
});
138139
});
139140

140-
test('cloudFrontDomainName property can be called multiple times', () => {
141+
testDeprecated('cloudFrontDomainName property can be called multiple times', () => {
141142
const stack = new Stack();
142143
const pool = new UserPool(stack, 'Pool');
143144
const domain = pool.addDomain('Domain', {
@@ -152,6 +153,27 @@ describe('User Pool Domain', () => {
152153
expect(cfDomainNameSecond).toEqual(cfDomainNameFirst);
153154
});
154155

156+
test('cloudFrontEndpoint property can be called without custom resource', () => {
157+
const stack = new Stack();
158+
const pool = new UserPool(stack, 'Pool');
159+
const domain = pool.addDomain('Domain', {
160+
cognitoDomain: {
161+
domainPrefix: 'cognito-domain-prefix',
162+
},
163+
});
164+
165+
const cloudFrontEndpoint = domain.cloudFrontEndpoint;
166+
167+
expect(stack.resolve(cloudFrontEndpoint)).toEqual({
168+
'Fn::GetAtt': [
169+
'PoolDomainCFC71F56',
170+
'CloudFrontDistribution',
171+
],
172+
});
173+
174+
Template.fromStack(stack).resourceCountIs('Custom::UserPoolCloudFrontDomainName', 0);
175+
});
176+
155177
test('import', () => {
156178
// GIVEN
157179
const stack = new Stack();

packages/aws-cdk-lib/rosetta/aws_cognito/default.ts-fixture

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Fixture with packages imported, but nothing else
2-
import { Duration, Stack } from 'aws-cdk-lib';
2+
import { CfnOutput, Duration, Stack } from 'aws-cdk-lib';
33
import { Construct } from 'constructs';
44
import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager';
55
import * as cognito from 'aws-cdk-lib/aws-cognito';

0 commit comments

Comments
 (0)