-
Notifications
You must be signed in to change notification settings - Fork 4k
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
fix(apigateway): rest api deployment does not depend on authorizers #23215
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.
✅ Updated pull request passes all PRLinter validations. Dissmissing previous PRLinter review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this PR actually solves the underlying issue. I'm going to see how this pairs with the reproduction code posted by the issue opener, once I can successfully reproduce.
private readonly authorizerProps: CfnAuthorizerProps; | ||
|
||
constructor(scope: Construct, id: string, props: CognitoUserPoolsAuthorizerProps) { | ||
super(scope, id); | ||
|
||
const restApiId = this.lazyRestApiId(); | ||
const resource = new CfnAuthorizer(this, 'Resource', { | ||
|
||
const authorizerProps = { | ||
name: props.authorizerName ?? Names.uniqueId(this), | ||
restApiId, | ||
type: 'COGNITO_USER_POOLS', | ||
providerArns: props.cognitoUserPools.map(userPool => userPool.userPoolArn), | ||
authorizerResultTtlInSeconds: props.resultsCacheTtl?.toSeconds(), | ||
identitySource: props.identitySource || 'method.request.header.Authorization', | ||
}); | ||
}; | ||
|
||
this.authorizerProps = authorizerProps; | ||
|
||
const resource = new CfnAuthorizer(this, 'Resource', authorizerProps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...why? Can we not leave this as the original more compact form?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to save authorizerProps
to a private instance variable so that we can use it in the _attachToApi
function
deployment.node.addDependency(this); | ||
deployment.addToLogicalId({ | ||
authorizer: this.authorizerProps, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it, the dependency just ensures resource deployment order, and it won't force an update to another resource. We really need a test to ensure that whenever the lambda function changes, the construct that needs to be updated is actually updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addToLogicalId()
ensures that whenever any of the authoriser props change, the deployment will get a new logical ID and a new deployment will be created
addDependency()
ensures that any changes to the authorizer are made before creating the new deployment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made a change and added a new test which checks that the deployment changes when the lambda function changes name
|
||
this.authorizerProps = authorizerProps; | ||
|
||
const resource = new CfnAuthorizer(this, 'Resource', authorizerProps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we leave this in the more compact form?
This PR has been in the CHANGES REQUESTED state for 3 weeks, and looks abandoned. To keep this PR from being closed, please continue work on it. If not, it will automatically be closed in a week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add an integration test that verifies that addToLogicalId()
is correctly used.
@@ -24,6 +24,7 @@ const restapi = new RestApi(stack, 'MyRestApi', { cloudWatchRole: true }); | |||
const authorizer = new RequestAuthorizer(stack, 'MyAuthorizer', { | |||
handler: authorizerFn, | |||
identitySources: [IdentitySource.header('Authorization'), IdentitySource.queryString('allow')], | |||
resultsCacheTtl: Duration.minutes(5), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why? This doesn't add anything to this integration test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I edited this test to re-run this integration test and verify that addToLogicalId()
worked correctly, however I will instead create a separate test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a breaking change so I also tried to add a feature flag
Pull request has been modified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct, this needs a feature flag. I think you've added it correctly.
if (!Token.isUnresolved(functionName)) { | ||
authorizerToken = JSON.stringify({ functionName }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can pass tokens to addToLogicalId()
, why do we check for them here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have copied the existing logic from here
I am guessing it is because the token can change which could cause the logical ID to change, even though the function name hadn't changed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other logic did not use this method, and addToLogicalId()
has a particular way of dealing with tokens. Please remove this token check and just pass it through to addToLogicalId()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the other logic I linked to is used in the addToLogicalId()
call here, however I have reworked the new code to handle unresolved tokens
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
1 similar comment
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
Pull request has been modified.
if (!Token.isUnresolved(functionName)) { | ||
authorizerToken = JSON.stringify({ functionName }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other logic did not use this method, and addToLogicalId()
has a particular way of dealing with tokens. Please remove this token check and just pass it through to addToLogicalId()
.
@@ -90,6 +93,34 @@ abstract class LambdaAuthorizer extends Authorizer implements IAuthorizer { | |||
} | |||
|
|||
this.restApiId = restApi.restApiId; | |||
|
|||
let functionName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason to do any of this if the feature flag is disabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved
Pull request has been modified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix!
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Closes #16554 (formerly #22808)
The Rest API deployment needs to depend on all authorizers attached to the API, so there is a new deployment if any of the authorizers change. This is similar to what is already done for
Method
s. Includes trivial change to integ test.Note - Because this will change the logical ID of existing deployments, this is technically a breaking change, so I am not sure if it requires a feature flag.
All Submissions:
Adding new Construct Runtime Dependencies:
New Features
yarn integ
to deploy the infrastructure and generate the snapshot (i.e.yarn integ
without--dry-run
)?By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license