Aws-cdk: APIGateway and Lambdas in separate stacks fails

Created on 19 Aug 2019  路  8Comments  路  Source: aws/aws-cdk

:bug: Bug Report

What is the problem?

I have what I would expect a very typical scenario: APIGateway that exposes several of my lambdas. I frequently have to delete the whole stack and would like to avoid destroying the APIGateway (so as not to change the URL and apikeys). So I wanted to split them to two stacks, one for the APIGateway and one for Lambdas. I first tried with CDK 1.1.0. This caused cyclic dependency errors (which I mentioned here. In hopes of it being fixed, I upgraded to 1.4.0. Now with the same setup I get:

cfn-reference.ts:108
      throw new Error(`Cross-stack reference (${context.scope.node.path} -> ${this.target.node.path}) has not been assigned a value--call prepare() first`);
            ^
Error: Resolution error: Resolution error: Resolution error: Cross-stack reference (ipk-PostiKioskiBackendStack-development -> ipk-PostiKioskiLambdaStack-development/ipk-ConfigLambda-development/Resource) has not been assigned a value--call prepare() first.
Object creation stack:
  at new Intrinsic (/Users/vertti/dev/posti/itsepalvelu-posti/posti-kioski-backend/node_modules/@aws-cdk/core/lib/private/intrinsic.ts:28:26)
  at new Reference (/Users/vertti/dev/posti/itsepalvelu-posti/posti-kioski-backend/node_modules/@aws-cdk/core/lib/reference.ts:21:5)

Reproduction Steps

Backend defined with:

const app = new core.App()
const stackLambda = new PostiKioskiLambdaStack(app, `ipk-PostiKioskiLambdaStack-${environment}`)
const stackBE = new PostiKioskiBackendStack(app, `ipk-PostiKioskiBackendStack-${environment}`, { configLambda: stackLambda.configLambda })

where PostiKioskiLambdaStack creates a lambda to a public configLambda property which is given in the props to stackBE.

The lambda in question is put inside a specific vpc:

    this.configLambda = new awsLambda.Function(this, `ipk-ConfigLambda-${environment}`, {
      role,
      vpc,

      code: awsLambda.Code.asset('resources'),
      handler: 'config_lambda.handler',
      runtime: awsLambda.Runtime.NODEJS_10_X,
    })

Verbose Log

https://gist.github.com/vertti/4883548b587774d1f1d2a75e78b640a1

Environment

  • CDK CLI Version: 1.4.0 (build 175471f)
  • OS: OSX Mojave
  • Language: TypeScript

Other information

There's been lots of fixes done for similar cases where Lambdas are in one stack and for example SNS is in another, all of those seemed to cause cyclic dependency errors.

@aws-cdaws-apigateway bug

All 8 comments

I am having the exact same issue. I put all lambda functions into an object

export interface Function {
  [name: string]: lambda.Function;
}

and exposed it by

public readonly functions: Function = {};

and add function to it in constructor

this.functions.testNpmModulesLambda = testNpmModulesLambda;

Same issue for me. I just refactored the RestApi creation into it's own stack, and all resource related stacks attempt to add resources and methods to it. But I get

'DevEnvironmentsRawDataStack' depends on 'DevEnvironmentsApiStack' (DevEnvironmentsRawDataStack/StoreRawData/ApiPermission.POST..raw-data -> DevEnvironmentsApiStack/Api/Resource.Ref). Adding this dependency (DevEnvironmentsApiStack/Api/Default/raw-data/get/Resource -> DevEnvironmentsRawDataStack/GetRawData/Resource.Arn) would create a cyclic reference.

I have the same error with @vertti .

/Users/whao/Developer/MINDeal/mindeal-serverless-dev/node_modules/@aws-cdk/core/lib/private/cfn-reference.ts:108
      throw new Error(`Cross-stack reference (${context.scope.node.path} -> ${this.target.node.path}) has not been assigned a value--call prepare() first`);
            ^
Error: Resolution error: Resolution error: Resolution error: Cross-stack reference (mindeal-apigateway-dev -> mindeal-lambda-stack-dev/test-npm-modules-lambda-dev/Resource) has not been assigned a value--call prepare() first.

I tried to exposed lambdas to my DyanmodbStack and it works fine.

Able to reproduce this with this CDK code -

#!/usr/bin/env node
import cdk = require('@aws-cdk/core');
import lambda = require('@aws-cdk/aws-lambda');
import apig = require('@aws-cdk/aws-apigateway');

class FirstStack extends cdk.Stack {
    public readonly firstLambda: lambda.Function;

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

      this.firstLambda = new lambda.Function(this, 'firstLambda', {
        code: lambda.Code.asset('resources'),
        handler: 'index.handler',
        runtime: lambda.Runtime.NODEJS_10_X,
      });
    }
}

interface SecondStackProps extends cdk.StackProps {
  readonly lambda: lambda.Function;
}

class SecondStack extends cdk.Stack{
  constructor(scope: cdk.Construct, id: string, props: SecondStackProps) {
    super(scope, id, props);

    const api = new apig.RestApi(this, 'BooksApi');
    api.root.addMethod('ANY');
    const booksApi = api.root.addResource('books');
    const lambdaIntegration = new apig.LambdaIntegration(props.lambda);
    booksApi.addMethod('GET', lambdaIntegration);
  }
}

const app = new cdk.App();
const first = new FirstStack(app, 'FirstStack');
new SecondStack(app, 'SecondStack', { lambda: first.firstLambda });
app.synth();

followed by running cdk synth

Update: Identified that the bug lies with API Gateway specific implementation of the Prepare phase, specifically within the LatestDeploymentResource.

The bug is here - https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-apigateway/lib/deployment.ts#L131.

The prepare phase, among other things, identifies intra-stack and cross-stack dependencies and registers them, for future resolution. It can be fully resolved only after the prepare phase is complete.

Update: I've found the cause and have a fix for this over here - https://github.com/aws/aws-cdk/pull/3906 - but is currently untestable because I've hit the cyclic reference error (https://github.com/aws/aws-cdk/issues/3000).

Working on identifying the root cause for the cyclic reference error.

Any updates on this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kawamoto picture kawamoto  路  3Comments

peterdeme picture peterdeme  路  3Comments

PaulMaddox picture PaulMaddox  路  3Comments

schof picture schof  路  3Comments

eladb picture eladb  路  3Comments