Skip to content
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

[apigatewayv2, lambda] Cyclic dependency between Lambda and HttpGateway #9075

Closed
MichaelHindley opened this issue Jul 15, 2020 · 0 comments · Fixed by #9100
Closed

[apigatewayv2, lambda] Cyclic dependency between Lambda and HttpGateway #9075

MichaelHindley opened this issue Jul 15, 2020 · 0 comments · Fixed by #9100
Assignees
Labels
@aws-cdk/aws-apigatewayv2 Related to Amazon API Gateway v2 bug This issue is a bug. p1

Comments

@MichaelHindley
Copy link

MichaelHindley commented Jul 15, 2020

Trying to have lambda in a separate stack than the httpgateway results in a cyclic dependency.

Similar issues fixed earlier: #4010

Reproduction Steps

aws.ts


#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { HttpGatewayStack } from '../lib/http-gateway-stack';
import LambdaStack from '../lib/lambda-stack'

const app = new cdk.App();
const lambdaStack = new LambdaStack(app, 'ApiLambdaStack')

new HttpGatewayStack(app, 'ApiHttpGatewayStack', {
  handler: lambdaStack.function
});

Lambda Stack:

import * as cdk from '@aws-cdk/core'
import * as lambda from '@aws-cdk/aws-lambda';
import * as path from 'path';

export default class LambdaStack extends cdk.Stack {
  public readonly function: lambda.Function

  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    this.function = new lambda.Function(this, 'ApiLambda', {
      runtime: lambda.Runtime.NODEJS_12_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '../../api')),
    });
  }
}

HttpGatewayStack:

import * as cdk from '@aws-cdk/core'
import * as httpGateway from '@aws-cdk/aws-apigatewayv2'
import * as lambda from '@aws-cdk/aws-lambda'

export class HttpGatewayStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props: cdk.StackProps & {
    handler: lambda.Function,
  }) {
    super(scope, id, props)

    const api = new httpGateway.HttpApi(this, 'Api', {
      defaultIntegration: new httpGateway.LambdaProxyIntegration({
        handler: props.handler
      }),
    })

  }
}

Error Log

Error: 'ApiLambdaStack' depends on 'ApiHttpGatewayStack' (ApiLambdaStack -> ApiHttpGatewayStack/Api/Resource.Ref). Adding this dependency (ApiHttpGatewayStack -> ApiLambdaStack/ApiLambda/Resource.Arn) would create a cyclic reference.

Environment

  • **CLI Version 1.51
  • **Framework Version: 1.51
  • **Node.js Version: v12.18.2
  • **OS : mac catalina
  • **Language (Version): typescript 3.9
@MichaelHindley MichaelHindley added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jul 15, 2020
@SomayaB SomayaB added @aws-cdk/aws-apigatewayv2 Related to Amazon API Gateway v2 @aws-cdk/aws-lambda Related to AWS Lambda labels Jul 15, 2020
@nija-at nija-at added p1 and removed @aws-cdk/aws-lambda Related to AWS Lambda needs-triage This issue or PR still needs to be triaged. labels Jul 16, 2020
nija-at pushed a commit that referenced this issue Jul 16, 2020
…unction

As part of Lambda proxy integration, a `AWS::Lambda::Permission`
resource is created to provide the HTTP service permission to invoke
the lambda function, creating the dependency, Permission → API.
The API, on the other hand, needs to refer to the Function's ARN and
hence creates the dependency, API → Function.

However, when the lambda function and the HTTP API are placed in
different stacks, this creates a cyclic dependency between these two
stacks.

A picture is worth a thousand words:

```
 +--------------------------------------------------------------+
 | Lambda stack                                                 |
 |                                                              |
 |    +-------------------+            +-----------------+      |
 |    |                   | via ARN    |                 |      |
 |    | Lambda Permission +----------->| Lambda Function |      |
 |    |                   |            |                 |      |
 |    +-------+-----------+            +-----------------+      |
 |            |                                ^                |
 +------------|--------------------------------|----------------+
              |via ARN                         |via ARN
              |                                |
 +------------|--------------------------------|-----------------+
 |            v                                |                 |
 |      +-----------+               +----------+---------+       |
 |      |           |    via ID     |                    |       |
 |      |  Http API |<--------------+  API Integration   |       |
 |      |           |               |                    |       |
 |      +-----------+               +--------------------+       |
 |                                                               |
 | API Gateway stack                                             |
 +---------------------------------------------------------------+
```

The fix here is to move the Lambda Permission resource into the same
stack as where the API integration is defined.

fixes #9075
nija-at pushed a commit that referenced this issue Jul 16, 2020
…unction

As part of Lambda proxy integration, a `AWS::Lambda::Permission`
resource is created to provide the HTTP service permission to invoke
the lambda function, creating the dependency, Permission → API.
The API, on the other hand, needs to refer to the Function's ARN and
hence creates the dependency, API → Function.

However, when the lambda function and the HTTP API are placed in
different stacks, this creates a cyclic dependency between these two
stacks.

A picture is worth a thousand words:

```
 +--------------------------------------------------------------+
 | Lambda stack                                                 |
 |                                                              |
 |    +-------------------+            +-----------------+      |
 |    |                   | via ARN    |                 |      |
 |    | Lambda Permission +----------->| Lambda Function |      |
 |    |                   |            |                 |      |
 |    +-------+-----------+            +-----------------+      |
 |            |                                ^                |
 +------------|--------------------------------|----------------+
              |via ARN                         |via ARN
              |                                |
 +------------|--------------------------------|-----------------+
 |            v                                |                 |
 |      +-----------+               +----------+---------+       |
 |      |           |    via ID     |                    |       |
 |      |  Http API |<--------------+  API Integration   |       |
 |      |           |               |                    |       |
 |      +-----------+               +--------------------+       |
 |                                                               |
 | API Gateway stack                                             |
 +---------------------------------------------------------------+
```

The fix here is to move the Lambda Permission resource into the same
stack as where the API integration is defined.

fixes #9075
nija-at pushed a commit that referenced this issue Jul 16, 2020
…unction

As part of Lambda proxy integration, a `AWS::Lambda::Permission`
resource is created to provide the HTTP service permission to invoke
the lambda function, creating the dependency, Permission → API.
The API, on the other hand, needs to refer to the Function's ARN and
hence creates the dependency, API → Function.

However, when the lambda function and the HTTP API are placed in
different stacks, this creates a cyclic dependency between these two
stacks.

A picture is worth a thousand words:

```
 +--------------------------------------------------------------+
 | Lambda stack                                                 |
 |                                                              |
 |    +-------------------+            +-----------------+      |
 |    |                   | via ARN    |                 |      |
 |    | Lambda Permission +----------->| Lambda Function |      |
 |    |                   |            |                 |      |
 |    +-------+-----------+            +-----------------+      |
 |            |                                ^                |
 +------------|--------------------------------|----------------+
              |via ARN                         |via ARN
              |                                |
 +------------|--------------------------------|-----------------+
 |            v                                |                 |
 |      +-----------+               +----------+---------+       |
 |      |           |    via ID     |                    |       |
 |      |  Http API |<--------------+  API Integration   |       |
 |      |           |               |                    |       |
 |      +-----------+               +--------------------+       |
 |                                                               |
 | API Gateway stack                                             |
 +---------------------------------------------------------------+
```

The fix here is to move the Lambda Permission resource into the same
stack as where the API integration is defined.

fixes #9075

BREAKING CHANGE: The parameter for the method `bind()` on
`IHttpRouteIntegration` has changed to accept one of type
`HttpRouteIntegrationBindOptions`. The previous parameter
`IHttpRoute` is now a property inside the new parameter under
the key `route`.
@mergify mergify bot closed this as completed in #9100 Aug 6, 2020
mergify bot pushed a commit that referenced this issue Aug 6, 2020
…unction (#9100)

As part of Lambda proxy integration, a `AWS::Lambda::Permission`
resource is created to provide the HTTP service permission to invoke
the lambda function, creating the dependency, Permission → API.
The API, on the other hand, needs to refer to the Function's ARN and
hence creates the dependency, API → Function.

However, when the lambda function and the HTTP API are placed in
different stacks, this creates a cyclic dependency between these two
stacks.

A picture is worth a thousand words:

```
 +--------------------------------------------------------------+
 | Lambda stack                                                 |
 |                                                              |
 |    +-------------------+            +-----------------+      |
 |    |                   | via ARN    |                 |      |
 |    | Lambda Permission +----------->| Lambda Function |      |
 |    |                   |            |                 |      |
 |    +-------+-----------+            +-----------------+      |
 |            |                                ^                |
 +------------|--------------------------------|----------------+
              |via ARN                         |via ARN
              |                                |
 +------------|--------------------------------|-----------------+
 |            v                                |                 |
 |      +-----------+               +----------+---------+       |
 |      |           |    via ID     |                    |       |
 |      |  Http API |<--------------+  API Integration   |       |
 |      |           |               |                    |       |
 |      +-----------+               +--------------------+       |
 |                                                               |
 | API Gateway stack                                             |
 +---------------------------------------------------------------+
```

The fix here is to move the Lambda Permission resource into the same
stack as where the API integration is defined, thereby breaking the
dependency cycle. 
Now the 'API Gateway stack' will depend one way on the 'Lambda
stack'.

fixes #9075

BREAKING CHANGE: The parameter for the method `bind()` on
`IHttpRouteIntegration` has changed to accept one of type
`HttpRouteIntegrationBindOptions`. The previous parameter
`IHttpRoute` is now a property inside the new parameter under
the key `route`.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
eladb pushed a commit that referenced this issue Aug 10, 2020
…unction (#9100)

As part of Lambda proxy integration, a `AWS::Lambda::Permission`
resource is created to provide the HTTP service permission to invoke
the lambda function, creating the dependency, Permission → API.
The API, on the other hand, needs to refer to the Function's ARN and
hence creates the dependency, API → Function.

However, when the lambda function and the HTTP API are placed in
different stacks, this creates a cyclic dependency between these two
stacks.

A picture is worth a thousand words:

```
 +--------------------------------------------------------------+
 | Lambda stack                                                 |
 |                                                              |
 |    +-------------------+            +-----------------+      |
 |    |                   | via ARN    |                 |      |
 |    | Lambda Permission +----------->| Lambda Function |      |
 |    |                   |            |                 |      |
 |    +-------+-----------+            +-----------------+      |
 |            |                                ^                |
 +------------|--------------------------------|----------------+
              |via ARN                         |via ARN
              |                                |
 +------------|--------------------------------|-----------------+
 |            v                                |                 |
 |      +-----------+               +----------+---------+       |
 |      |           |    via ID     |                    |       |
 |      |  Http API |<--------------+  API Integration   |       |
 |      |           |               |                    |       |
 |      +-----------+               +--------------------+       |
 |                                                               |
 | API Gateway stack                                             |
 +---------------------------------------------------------------+
```

The fix here is to move the Lambda Permission resource into the same
stack as where the API integration is defined, thereby breaking the
dependency cycle. 
Now the 'API Gateway stack' will depend one way on the 'Lambda
stack'.

fixes #9075

BREAKING CHANGE: The parameter for the method `bind()` on
`IHttpRouteIntegration` has changed to accept one of type
`HttpRouteIntegrationBindOptions`. The previous parameter
`IHttpRoute` is now a property inside the new parameter under
the key `route`.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-apigatewayv2 Related to Amazon API Gateway v2 bug This issue is a bug. p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants