Skip to content

Commit d912e46

Browse files
fix merge conflicts
Signed-off-by: Vinayak Kukreja <[email protected]>
2 parents 5862f7a + 9b2a45a commit d912e46

39 files changed

+1252
-182
lines changed

packages/@aws-cdk/aws-apigateway/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,18 @@ to allow users revert the stage to an old deployment manually.
945945
[Deployment]: https://docs.aws.amazon.com/apigateway/api-reference/resource/deployment/
946946
[Stage]: https://docs.aws.amazon.com/apigateway/api-reference/resource/stage/
947947

948+
In order to also create a new deployment when changes are made to any authorizer attached to the API,
949+
the `@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId` [feature flag](https://docs.aws.amazon.com/cdk/v2/guide/featureflags.html) can be enabled. This can be set
950+
in the `cdk.json` file.
951+
952+
```json
953+
{
954+
"context": {
955+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true
956+
}
957+
}
958+
```
959+
948960
## Custom Domains
949961

950962
To associate an API with a custom domain, use the `domainName` configuration when

packages/@aws-cdk/aws-apigateway/lib/authorizers/cognito.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as cognito from '@aws-cdk/aws-cognito';
2-
import { Duration, Lazy, Names, Stack } from '@aws-cdk/core';
2+
import { Duration, FeatureFlags, Lazy, Names, Stack } from '@aws-cdk/core';
3+
import { APIGATEWAY_AUTHORIZER_CHANGE_DEPLOYMENT_LOGICAL_ID } from '@aws-cdk/cx-api';
34
import { Construct } from 'constructs';
4-
import { CfnAuthorizer } from '../apigateway.generated';
5+
import { CfnAuthorizer, CfnAuthorizerProps } from '../apigateway.generated';
56
import { Authorizer, IAuthorizer } from '../authorizer';
67
import { AuthorizationType } from '../method';
78
import { IRestApi } from '../restapi';
@@ -64,18 +65,25 @@ export class CognitoUserPoolsAuthorizer extends Authorizer implements IAuthorize
6465

6566
private restApiId?: string;
6667

68+
private readonly authorizerProps: CfnAuthorizerProps;
69+
6770
constructor(scope: Construct, id: string, props: CognitoUserPoolsAuthorizerProps) {
6871
super(scope, id);
6972

7073
const restApiId = this.lazyRestApiId();
71-
const resource = new CfnAuthorizer(this, 'Resource', {
74+
75+
const authorizerProps = {
7276
name: props.authorizerName ?? Names.uniqueId(this),
7377
restApiId,
7478
type: 'COGNITO_USER_POOLS',
7579
providerArns: props.cognitoUserPools.map(userPool => userPool.userPoolArn),
7680
authorizerResultTtlInSeconds: props.resultsCacheTtl?.toSeconds(),
7781
identitySource: props.identitySource || 'method.request.header.Authorization',
78-
});
82+
};
83+
84+
this.authorizerProps = authorizerProps;
85+
86+
const resource = new CfnAuthorizer(this, 'Resource', authorizerProps);
7987

8088
this.authorizerId = resource.ref;
8189
this.authorizerArn = Stack.of(this).formatArn({
@@ -96,6 +104,16 @@ export class CognitoUserPoolsAuthorizer extends Authorizer implements IAuthorize
96104
}
97105

98106
this.restApiId = restApi.restApiId;
107+
108+
const addToLogicalId = FeatureFlags.of(this).isEnabled(APIGATEWAY_AUTHORIZER_CHANGE_DEPLOYMENT_LOGICAL_ID);
109+
110+
const deployment = restApi.latestDeployment;
111+
if (deployment && addToLogicalId) {
112+
deployment.node.addDependency(this);
113+
deployment.addToLogicalId({
114+
authorizer: this.authorizerProps,
115+
});
116+
}
99117
}
100118

101119
/**

packages/@aws-cdk/aws-apigateway/lib/authorizers/lambda.ts

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import * as iam from '@aws-cdk/aws-iam';
22
import * as lambda from '@aws-cdk/aws-lambda';
3-
import { Arn, ArnFormat, Duration, Lazy, Names, Stack } from '@aws-cdk/core';
3+
import { Arn, ArnFormat, Duration, FeatureFlags, Lazy, Names, Stack } from '@aws-cdk/core';
4+
import { APIGATEWAY_AUTHORIZER_CHANGE_DEPLOYMENT_LOGICAL_ID } from '@aws-cdk/cx-api';
45
import { Construct } from 'constructs';
5-
import { CfnAuthorizer } from '../apigateway.generated';
6+
import { CfnAuthorizer, CfnAuthorizerProps } from '../apigateway.generated';
67
import { Authorizer, IAuthorizer } from '../authorizer';
78
import { IRestApi } from '../restapi';
89

@@ -69,6 +70,8 @@ abstract class LambdaAuthorizer extends Authorizer implements IAuthorizer {
6970

7071
protected restApiId?: string;
7172

73+
protected abstract readonly authorizerProps: CfnAuthorizerProps;
74+
7275
protected constructor(scope: Construct, id: string, props: LambdaAuthorizerProps) {
7376
super(scope, id);
7477

@@ -90,6 +93,28 @@ abstract class LambdaAuthorizer extends Authorizer implements IAuthorizer {
9093
}
9194

9295
this.restApiId = restApi.restApiId;
96+
97+
const deployment = restApi.latestDeployment;
98+
const addToLogicalId = FeatureFlags.of(this).isEnabled(APIGATEWAY_AUTHORIZER_CHANGE_DEPLOYMENT_LOGICAL_ID);
99+
100+
if (deployment && addToLogicalId) {
101+
let functionName;
102+
103+
if (this.handler instanceof lambda.Function) {
104+
// if not imported, attempt to get the function name, which
105+
// may be a token
106+
functionName = (this.handler.node.defaultChild as lambda.CfnFunction).functionName;
107+
} else {
108+
// if imported, the function name will be a token
109+
functionName = this.handler.functionName;
110+
}
111+
112+
deployment.node.addDependency(this);
113+
deployment.addToLogicalId({
114+
authorizer: this.authorizerProps,
115+
authorizerToken: functionName,
116+
});
117+
}
93118
}
94119

95120
/**
@@ -163,11 +188,14 @@ export class TokenAuthorizer extends LambdaAuthorizer {
163188

164189
public readonly authorizerArn: string;
165190

191+
protected readonly authorizerProps: CfnAuthorizerProps;
192+
166193
constructor(scope: Construct, id: string, props: TokenAuthorizerProps) {
167194
super(scope, id, props);
168195

169196
const restApiId = this.lazyRestApiId();
170-
const resource = new CfnAuthorizer(this, 'Resource', {
197+
198+
const authorizerProps: CfnAuthorizerProps = {
171199
name: props.authorizerName ?? Names.uniqueId(this),
172200
restApiId,
173201
type: 'TOKEN',
@@ -176,7 +204,11 @@ export class TokenAuthorizer extends LambdaAuthorizer {
176204
authorizerResultTtlInSeconds: props.resultsCacheTtl?.toSeconds(),
177205
identitySource: props.identitySource || 'method.request.header.Authorization',
178206
identityValidationExpression: props.validationRegex,
179-
});
207+
};
208+
209+
this.authorizerProps = authorizerProps;
210+
211+
const resource = new CfnAuthorizer(this, 'Resource', authorizerProps);
180212

181213
this.authorizerId = resource.ref;
182214
this.authorizerArn = Stack.of(this).formatArn({
@@ -221,6 +253,8 @@ export class RequestAuthorizer extends LambdaAuthorizer {
221253

222254
public readonly authorizerArn: string;
223255

256+
protected readonly authorizerProps: CfnAuthorizerProps;
257+
224258
constructor(scope: Construct, id: string, props: RequestAuthorizerProps) {
225259
super(scope, id, props);
226260

@@ -229,15 +263,20 @@ export class RequestAuthorizer extends LambdaAuthorizer {
229263
}
230264

231265
const restApiId = this.lazyRestApiId();
232-
const resource = new CfnAuthorizer(this, 'Resource', {
266+
267+
const authorizerProps: CfnAuthorizerProps = {
233268
name: props.authorizerName ?? Names.uniqueId(this),
234269
restApiId,
235270
type: 'REQUEST',
236271
authorizerUri: lambdaAuthorizerArn(props.handler),
237272
authorizerCredentials: props.assumeRole?.roleArn,
238273
authorizerResultTtlInSeconds: props.resultsCacheTtl?.toSeconds(),
239274
identitySource: props.identitySources.map(is => is.toString()).join(','),
240-
});
275+
};
276+
277+
this.authorizerProps = authorizerProps;
278+
279+
const resource = new CfnAuthorizer(this, 'Resource', authorizerProps);
241280

242281
this.authorizerId = resource.ref;
243282
this.authorizerArn = Stack.of(this).formatArn({

packages/@aws-cdk/aws-apigateway/test/authorizers/cognito.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,58 @@ describe('Cognito Authorizer', () => {
6363

6464
expect(authorizer.authorizerArn.endsWith(`/authorizers/${authorizer.authorizerId}`)).toBeTruthy();
6565
});
66+
67+
test('rest api depends on the authorizer when @aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId is enabled', () => {
68+
const stack = new Stack();
69+
stack.node.setContext('@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId', true);
70+
const userPool1 = new cognito.UserPool(stack, 'UserPool');
71+
72+
const authorizer = new CognitoUserPoolsAuthorizer(stack, 'Authorizer', {
73+
cognitoUserPools: [userPool1],
74+
});
75+
76+
const restApi = new RestApi(stack, 'Api');
77+
78+
restApi.root.addMethod('ANY', undefined, {
79+
authorizer,
80+
authorizationType: AuthorizationType.COGNITO,
81+
});
82+
83+
const template = Template.fromStack(stack);
84+
85+
const authorizerId = Object.keys(template.findResources('AWS::ApiGateway::Authorizer'))[0];
86+
const deployment = Object.values(template.findResources('AWS::ApiGateway::Deployment'))[0];
87+
88+
expect(deployment.DependsOn).toEqual(expect.arrayContaining([authorizerId]));
89+
});
90+
91+
test('a new deployment is created when a cognito user pool is re-created and @aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId is enabled', () => {
92+
const createApiTemplate = (userPoolId: string) => {
93+
const stack = new Stack();
94+
stack.node.setContext('@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId', true);
95+
96+
const userPool = new cognito.UserPool(stack, userPoolId);
97+
98+
const auth = new CognitoUserPoolsAuthorizer(stack, 'myauthorizer', {
99+
resultsCacheTtl: Duration.seconds(0),
100+
cognitoUserPools: [userPool],
101+
});
102+
103+
const restApi = new RestApi(stack, 'myrestapi');
104+
restApi.root.addMethod('ANY', undefined, {
105+
authorizer: auth,
106+
authorizationType: AuthorizationType.COGNITO,
107+
});
108+
109+
return Template.fromStack(stack);
110+
};
111+
112+
const oldTemplate = createApiTemplate('foo');
113+
const newTemplate = createApiTemplate('bar');
114+
115+
const oldDeploymentId = Object.keys(oldTemplate.findResources('AWS::ApiGateway::Deployment'))[0];
116+
const newDeploymentId = Object.keys(newTemplate.findResources('AWS::ApiGateway::Deployment'))[0];
117+
118+
expect(oldDeploymentId).not.toEqual(newDeploymentId);
119+
});
66120
});

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.js.snapshot/CognitoUserPoolsAuthorizerInteg.assets.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
2-
"version": "20.0.0",
2+
"version": "22.0.0",
33
"files": {
4-
"551baa1ebfdea9d8d905ffd1e2e8ac09982d0a49e669c97ad0d8f8c092cb96df": {
4+
"81ccfaff55790eb0a0ba90c4ede5ca2168072939afb21004c5dcb5ca74295b40": {
55
"source": {
66
"path": "CognitoUserPoolsAuthorizerInteg.template.json",
77
"packaging": "file"
88
},
99
"destinations": {
1010
"current_account-current_region": {
1111
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12-
"objectKey": "551baa1ebfdea9d8d905ffd1e2e8ac09982d0a49e669c97ad0d8f8c092cb96df.json",
12+
"objectKey": "81ccfaff55790eb0a0ba90c4ede5ca2168072939afb21004c5dcb5ca74295b40.json",
1313
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
1414
}
1515
}

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.js.snapshot/CognitoUserPoolsAuthorizerInteg.template.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
"UpdateReplacePolicy": "Retain",
106106
"DeletionPolicy": "Retain"
107107
},
108-
"myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a": {
108+
"myrestapiDeployment419B1464d5146a3a0aa3a9f79024a52930571dc6": {
109109
"Type": "AWS::ApiGateway::Deployment",
110110
"Properties": {
111111
"RestApiId": {
@@ -114,6 +114,7 @@
114114
"Description": "Automatically created by the RestApi construct"
115115
},
116116
"DependsOn": [
117+
"myauthorizer23CB99DD",
117118
"myrestapiANY94B0497F"
118119
]
119120
},
@@ -124,7 +125,7 @@
124125
"Ref": "myrestapi551C8392"
125126
},
126127
"DeploymentId": {
127-
"Ref": "myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a"
128+
"Ref": "myrestapiDeployment419B1464d5146a3a0aa3a9f79024a52930571dc6"
128129
},
129130
"StageName": "prod"
130131
},
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"version":"20.0.0"}
1+
{"version":"22.0.0"}

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.js.snapshot/cognitoauthorizerDefaultTestDeployAssert4551574C.assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "20.0.0",
2+
"version": "22.0.0",
33
"files": {
44
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
55
"source": {
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
2-
"version": "20.0.0",
2+
"version": "22.0.0",
33
"testCases": {
44
"cognito-authorizer/DefaultTest": {
55
"stacks": [
66
"CognitoUserPoolsAuthorizerInteg"
77
],
8-
"assertionStack": "cognito-authorizer/DefaultTest/DeployAssert"
8+
"assertionStack": "cognito-authorizer/DefaultTest/DeployAssert",
9+
"assertionStackName": "cognitoauthorizerDefaultTestDeployAssert4551574C"
910
}
1011
}
1112
}

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.js.snapshot/manifest.json

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
{
2-
"version": "20.0.0",
2+
"version": "22.0.0",
33
"artifacts": {
4-
"Tree": {
5-
"type": "cdk:tree",
6-
"properties": {
7-
"file": "tree.json"
8-
}
9-
},
104
"CognitoUserPoolsAuthorizerInteg.assets": {
115
"type": "cdk:asset-manifest",
126
"properties": {
@@ -23,7 +17,7 @@
2317
"validateOnSynth": false,
2418
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
2519
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
26-
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/551baa1ebfdea9d8d905ffd1e2e8ac09982d0a49e669c97ad0d8f8c092cb96df.json",
20+
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/81ccfaff55790eb0a0ba90c4ede5ca2168072939afb21004c5dcb5ca74295b40.json",
2721
"requiresBootstrapStackVersion": 6,
2822
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
2923
"additionalDependencies": [
@@ -72,7 +66,7 @@
7266
"/CognitoUserPoolsAuthorizerInteg/myrestapi/Deployment/Resource": [
7367
{
7468
"type": "aws:cdk:logicalId",
75-
"data": "myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a"
69+
"data": "myrestapiDeployment419B1464d5146a3a0aa3a9f79024a52930571dc6"
7670
}
7771
],
7872
"/CognitoUserPoolsAuthorizerInteg/myrestapi/DeploymentStage.prod/Resource": [
@@ -104,6 +98,15 @@
10498
"type": "aws:cdk:logicalId",
10599
"data": "CheckBootstrapVersion"
106100
}
101+
],
102+
"myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a": [
103+
{
104+
"type": "aws:cdk:logicalId",
105+
"data": "myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a",
106+
"trace": [
107+
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
108+
]
109+
}
107110
]
108111
},
109112
"displayName": "CognitoUserPoolsAuthorizerInteg"
@@ -154,6 +157,12 @@
154157
]
155158
},
156159
"displayName": "cognito-authorizer/DefaultTest/DeployAssert"
160+
},
161+
"Tree": {
162+
"type": "cdk:tree",
163+
"properties": {
164+
"file": "tree.json"
165+
}
157166
}
158167
}
159168
}

0 commit comments

Comments
 (0)