Open rjoseph-resilient opened 4 years ago
Hi,
For anyone else who may run into this...
I have worked around this by importing the Lambda via its ARN instead and setting up a custom Role.
Example:
import * as iam from '@aws-cdk/aws-iam';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apigateway from '@aws-cdk/aws-apigateway';
const tokenAuthLambdaFn = lambda.Function.fromFunctionArn(
this,
'tokenAuthoriser',
`arn:aws:lambda:${region}:${account}:function:my-lambda-tokenAuthoriser`
);
// Role and policies to allow TokenAuthoriser Lambda to be invoked by API Gateway
const invokeTokenAuthoriserRole = new iam.Role(this, 'Role', {
roleName: 'my-api-gateway-role`,
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com')
});
const invokeTokenAuthoriserPolicyStatement = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
sid: 'AllowInvokeLambda',
resources: ['*'], // or the ARN of your TokenAuthoriser Lambda
actions: ['lambda:InvokeFunction']
});
const policy = new iam.Policy(this, 'Policy', {
policyName: 'my-api-gateway-policy',
roles: [invokeTokenAuthoriserRole],
statements: [invokeTokenAuthoriserPolicyStatement ]
});
const authorizer = new apigateway.TokenAuthorizer(this, 'TokenAuthoriser', {
handler: tokenAuthLambdaFn,
assumeRole: invokeTokenAuthoriserRole
});
Finally I apply the authorizer to the required method:
rest.addResource('endpoint').addMethod('POST', lambdaIntegration, {
requestModels: { 'application/json': new apigateway.Model() },
requestValidator,
authorizer // This is the TokenAuthorizer from above example
});
}
Hope you find this helpful.
Kind Regards,
Ricardo
This is likely happening because the AWS::Lambda::Permission
resource type depends on the the ARN of the authorizer in order to set up the correct permissions, while the authorizer depends on the lambda function -
+----------------+
|Stack 2 |
| |
+----------------+ | |
|Stack 1 | | +----------+ |
| | | | | |
| +-----------+ | | | Lambda | |
| | | | +------>| Function | |
| | Rest API | | | | | | |
| | | | | | +----------+ |
| +-----+-----+ | | | ^ |
| | | | | | |
| | | | | | |
| v | | | | |
| +------------+ | | | +-----+------+ |
| | +-------+ | | | |
| | Authorizer | | | | Lambda | |
| | |<--------------+ Permission | |
| +------------+ | | | | |
+----------------+ | +------------+ |
| |
+----------------+
This causes the two stacks to depend on each other.
The fix likely involves moving the Lambda Permission
object to the source stack (i.e., Stack 1) by setting the correct scope
property on the addPermissions()
API.
@nija-at Any updates/ETA on this issue?
@nija-at: looks like this is still an unresolved issue. I'm still running into it with CDK version (1.120.0 (build 6c15150)). I'm not fond of workaround mentioned above. thanks...
Sorry, we are unable to attend to this issue right now.
We are accepting pull requests if anyone is interested in submitting a fix.
This is problematic, I would love to see this issue fixed.
+1
Facing same problem. Not sure how, but it works when I use HttpLambdaAuthorizer
+ Http API with the same dependency graph as stated in this issue. But when I switched to TokenAuthorizer
+ Rest API, I got the issue.
This is still an issue, is there any timeline on this?
:question: General Issue
The Question
Hi,
I have two separate stacks, one for my API Gateway and another for my Lambda that is used as the token authoriser. The Lambda function is then passed to API Gateway via props and is used as the token authoriser. When building the aws-cdk errors mentioning "would create a cyclic reference." regarding the API Gateway and the token authoriser referencing the Lambda.
I have provided examples and a stack trace under Other information for further details.
Please let me know how this may be resolved (Not sure if this is a bug (seems like a bug) or as designed or user error)?
P.S. My preference is to have my Lambdas in a separate stack (Allows me to deploy/undeploy Lambdas independently from the API Gateway), however if this is not possible at this moment in time, please let me know.
Kind Regards,
RJ
Environment
Other information
Below are examples of the stacks:
Stack 1 - API Gateway
Stack 2 - Lambda - TokenAuthoriser
As you can see in Stack 1 above, two Lambdas are passed to the API Gateway construct. The first (integrationLambdaFn) is passed to
apigateway.LambdaIntegration(integrationLambdaFn)
and does not cause the cyclic dependency error. However the second (tokenAuthoriserLambdaFn) passed to the apigateway.TokenAuthorizer via the apigateway.TokenAuthorizerProps props causes the cyclic dependency error.Below is an example stack trace: