Skip to content

aws-lambda-nodejs: Overrides of handler always get prefixed with index. #24403

@huntharo

Description

@huntharo

Describe the bug

Some lambda extensions require changing the handler to a specific value but aws-lambda-nodejs always prefixes this with index., breaking the intended values.

For example, the AWS Lambda Web Adapter requires run.sh:

https://github.com/awslabs/aws-lambda-web-adapter#lambda-functions-packaged-as-zip-package-for-aws-managed-runtimes

image

For example, an extension from NewRelic requiresnewrelic-lambda-wrapper.handler:

https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-your-own/

image

Expected Behavior

If a handler is set to a value with a . in it then the index. prefix logic should not apply.

Current Behavior

Values like run.sh are turned into index.run.sh

Reproduction Steps

new lambdaNodejs.NodejsFunction(this, 'my-lambda-func', {
      functionName: 'my-lambda-name',
      architecture: lambda.Architecture.ARM_64,
      entry: './packages/my-lambda/src/index.ts',
      handler: 'run.sh',                                                             // <--- this will turn into `index.run.sh`
      logRetention: logs.RetentionDays.ONE_MONTH,
      memorySize: 1769,
      timeout: cdk.Duration.minutes(15),
      runtime: lambda.Runtime.NODEJS_16_X,
      bundling: {
        sourceMap: !shared.isTestBuild,
        minify: !shared.isTestBuild,
commandHooks: {
            beforeInstall: () => [],
            beforeBundling: () => [],
            afterBundling: (inputDir: string, outputDir: string) => {
              return [
                `${os.platform() === 'win32' ? 'copy' : 'cp'} ${path.join(
                  inputDir,
                  'packages',
                  'my-lambda',
                  'run.sh'                                                                  // <--- this won't be found because handler looks for `index.run.sh`
                )} ${outputDir}`,
              ];
            },
          },
      },
    });

Possible Solution

I have personally been using a patch for this for 15 months that does not add the index. prefix if the user intentionally sets the handler to a value that includes a .:

--- a/node_modules/@aws-cdk/aws-lambda-nodejs/lib/function.js
+++ b/node_modules/@aws-cdk/aws-lambda-nodejs/lib/function.js
@@ -44,7 +44,7 @@ class NodejsFunction extends lambda.Function {
                 depsLockFilePath,
                 projectRoot,
             }),
-            handler: `index.${handler}`,
+            handler: handler.indexOf('.') !== -1 ? `${handler}` : `index.${handler}`,
         });
         // Enable connection reuse for aws-sdk
         if ((_g = props.awsSdkConnectionReuse) !== null && _g !== void 0 ? _g : true) {

The code is unchanged, essentially, even today:

handler: `index.${handler}`,

Additional Information/Context

aws-lambda-nodejs is intended to the an easy button for bundling Node.js apps, and it largely performs well at that task.

But if the user intentionally overrides the handler value then the easy button quickly becomes more difficult as you either have to patch this behavior with patch-package after tracing it through in a debugger, or you have to remove all usage of aws-lambda-nodejs just so that you can set the handler and not have it get mangled. Neither of these turn out to be that easy :)

CDK CLI Version

2.66.1

Framework Version

2.66.1

Node.js Version

18

OS

Mac

Language

Typescript

Language Version

n/a

Other information

I can submit a pull request if the solution is thought to be adequate.

If the solution works but needs a feature flag to be enabled I can submit it that way too. Let me know if there is an alternative approach and I'll see if I can submit it that way.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions