API Gateway and Lambda TokenAuthorizer in different stacks causing cyclic reference error
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
## :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
- **CDK CLI Version:** 1.42.0 (build 3b64241)
- **Module Version:** all modules versions are 1.42.0 (i.e. apigateway, lambda, cdk, iam)
- **OS:** Ubuntu
- **Language:** TypeScript
### Other information
**Below are examples of the stacks:**
Stack 1 - API Gateway
```
constructor(stack: cdk.Stack, { integrationLambdaFn, tokenAuthoriserLambdaFn}: Props) {
const api = new apigateway.RestApi(this, 'RestApi', {
description: 'My API Gateway REST API',
restApiName: 'MyApiGatewayRestApi',
policy: policyDocument,
deployOptions: {
stageName: 'stage'
},
defaultIntegration: new apigateway.LambdaIntegration(integrationLambdaFn),
defaultMethodOptions: {
authorizer: new apigateway.TokenAuthorizer(this, 'MyTokenAuthoriser', {
handler: tokenAuthoriserLambdaFn
})
}
});
```
Stack 2 - Lambda - TokenAuthoriser
```
this.tokenAuthoriserLambdaFn= new lambda.Function(scope, 'Function', {
functionName: 'myTokenAuthoriser',
runtime: lambda.Runtime.NODEJS_12_X,
code: lambda.Code.fromAsset('./lambda'),
handler: 'index.myTokenAuthoriserHandler',
role: myRole,
timeout: cdk.Duration.seconds(15),
tracing: lambda.Tracing.ACTIVE,
vpc,
securityGroups: [securityGroup1]
});
this.tokenAuthoriserLambdaFn.node.addDependency(policy);
```
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:**
```
Error: 'lambda' depends on 'apigateway' (lambda -> apigateway/MyApiGateWay/RestApi/Resource.Ref, lambda -> apigateway/MyApiGateWay/TokenAuthoriser/Resource.Ref). Adding this dependency (apigateway -> lambda/MyTokenAuthoriser/Function/Resource.Arn) would create a cyclic reference.
at ApiGatewayStack._addAssemblyDependency (/home/builds/project/node_modules/@aws-cdk/core/lib/stack.js:409:19)
at Object.addDependency (/home/builds/project/node_modules/@aws-cdk/core/lib/deps.js:39:24)
at ApiGatewayStack.addDependency (/home/builds/project/node_modules/@aws-cdk/core/lib/stack.js:188:16)
at resolveValue (/home/builds/project/node_modules/@aws-cdk/core/lib/private/refs.js:84:14)
at Object.resolveReferences (/home/builds/project/node_modules/@aws-cdk/core/lib/private/refs.js:26:30)
at Object.prepareApp (/home/builds/project/node_modules/@aws-cdk/core/lib/private/prepare-app.js:35:16)
at App.prepare (/home/builds/project/node_modules/@aws-cdk/core/lib/app.js:81:23)
at App.onPrepare (/home/builds/project/node_modules/@aws-cdk/core/lib/construct-compat.js:71:14)
at Node.prepare (/home/builds/project/node_modules/constructs/lib/construct.js:365:20)
at Node.synthesize (/home/builds/project/node_modules/constructs/lib/construct.js:323:14)
```
Contributor guide
Research direction
Start with the Stack 1 and Stack 2 TypeScript examples, then trace the reported dependency through @aws-cdk/core/lib/stack.js and @aws-cdk/core/lib/private/refs.js. Reproduce synthesis with the API Gateway TokenAuthorizer and Lambda in separate stacks; done means the cyclic-reference error is resolved while the intended stack separation remains supported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- api, cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100