aws / aws/aws-cdk

API Gateway and Lambda TokenAuthorizer in different stacks causing cyclic reference error

Open
#8,241 9 comments 6 reactions 0 assignees View on GitHub
@aws-cdk/aws-apigateway bug cross-stack effort/small p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.