aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.58k stars 3.88k forks source link

aws-lambda-nodejs: Not working with NestedStack #23181

Closed Depaa closed 1 year ago

Depaa commented 1 year ago

Describe the bug

When creating lambdas with aws-lambda-nodejs in a NestedStack it takes the wrong entry point to the lambda function. I think it takes the root folder only when deploying.

Expected Behavior

It deploys the lambdas following the right entry point specified

Current Behavior

It deploys the lambdas using the root folder as entry point, it breaks every lambda within the nested stack

Reproduction Steps

api gateway stack

import { App, Stack, StackProps } from 'aws-cdk-lib';
import { RestApi } from 'aws-cdk-lib/aws-apigateway';
import { PostsApiStack } from './posts';
import { DeployStack } from './deployment';

export class apiGatewayStack extends Stack {
  constructor(scope: App, props: StackProps) {
    super(scope, props);

    const api = new RestApi(this, 'RestApi', {
      deploy: true,
    });

    const postsApiStack = new PostsApiStack(
      this,
      'PostApi',
      {
        apiId: api.restApiId,
        apiRootResourceId: api.restApiRootResourceId,
      }
    );

    new DeployStack(
      this,
      'DeployRestApi',
      {
        apiId: api.restApiId,
        methods: postsApiStack.methods,
      }
    );
  };
}

posts api nested stack

import { NestedStack, NestedStackProps } from 'aws-cdk-lib';
import { Method, RestApi, LambdaIntegration } from 'aws-cdk-lib/aws-apigateway';
import { Runtime, Architecture } from 'aws-cdk-lib/aws-lambda';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Construct } from 'constructs';
import { join } from 'path';

interface PostStackProps extends NestedStackProps {
  readonly apiId: string;
  readonly apiRootResourceId: string;
}

export class PostsApiStack extends NestedStack {
  public readonly methods: Method[] = [];

  constructor(scope: Construct, props: PostStackProps) {
    super(scope, props);

    const api = RestApi.fromRestApiAttributes(this, 'RestApiPost', {
      restApiId: props.apiId,
      rootResourceId: props.apiRootResourceId,
    });

    const resourceApi = api.root.addResource('posts');

    const lambda =  new NodejsFunction(
      this,
      'lambdaTest',
      {
        architecture: Architecture.ARM_64,
        runtime: Runtime.NODEJS_18_X,
        bundling: {
          minify: false,
          target: 'node18',
          keepNames: true,
        },
        functionName: 'test',
        entry: join(__dirname, `../../../src/functions/test/index.ts`),
      }
    );

    return resourceApi.addMethod(
      'GET',
      new LambdaIntegration(lambda, { proxy: true }),
    );
  }
}

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.42.1 (build 48a95f1)

Framework Version

No response

Node.js Version

v16.17.0

OS

Windows

Language

Typescript

Language Version

Typescript (4.9.3)

Other information

No response

peterwoodworth commented 1 year ago

I wasn't able to reproduce this, I can deploy the exact same NodejsFunction both inside a nested stack and outside. What is the specific error message you're getting?

Depaa commented 1 year ago

Thank you @peterwoodworth for answering.

I wrote the code in this repo https://github.com/Depaa/aws-sdk-nodejs-nested-function

after the deploy this is how the lambda package turn out: image

I do have a work around which creates another stack, but I do not like it because I had to create a new deploy for each main resource.

peterwoodworth commented 1 year ago

Thanks for sharing you repo @Depaa,

I cloned it and am still unable to reproduce the behavior you describe.

Just to make sure Im not missing anything, where exactly are you finding that the lambda package looks like that?

Also, is this happening in prod, non prod, or both?

github-actions[bot] commented 1 year ago

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

reecefenwick commented 7 months ago

@peterwoodworth I believe that screenshot will be the function code artefact, so when you export the lambda function from the AWS console, inside the zip is what is in that screenshot, his entire project.. rather than the single js bundle from esbuild

I'm having the same issue, but worse in that I can't even get it to deploy because my project as a whole is too large. It simply fails to deploy because the ZIP file is 1GB

I use NodejsFunction heavily across other stacks, as soon as it moves into a nested stack it starts packaging the entire project and from what I can tell, it doesn't even run esbuild to bundle

I haven't gotten to the stage of workaround yet, I am still hopeful to find the root cause here.. but worst case I will do what @Depaa mentioned (deploy as separate stacks, not ideal) or I might just take over bundling myself and drop usage of NodejsFunction

reecefenwick commented 7 months ago

Just done some more digging and have identified a difference internally within CDK here

I shall keep digging 🙃

reecefenwick commented 7 months ago

Looks like this issue is related (or the same) to this one https://github.com/aws/aws-cdk/issues/12898