awslabs / aws-crt-nodejs

NodeJS bindings for the AWS Common Runtime.
Apache License 2.0
40 stars 26 forks source link

Node binaries not loading from binding.js when hoisted to root of node_modules #523

Open justin-masse opened 10 months ago

justin-masse commented 10 months ago

Describe the bug

When using @aws-sdk/signature-v4-crt it is getting an error that AWS CRT binary not present in any of the following locations:

I have verified the aws-crt package is present and I can see the binary in bin/linux-x64-glibc as aws-crt-nodejs.node. The problem is that it gets hoisted to the top level of node_modules by yarn instead of living under sigv4 package.

Runtime is AWS Lambda Node18

Expected Behavior

Not to get this error

Current Behavior

When using sigv4 CRT signing methods it gives error:

"Error: AWS CRT binary not present in any of the following locations:",
        "\t/bin/linux-x64-glibc/aws-crt-nodejs",
        "    at node_modules/aws-crt/dist/native/binding.js (/var/task/index.js:781126:13)",
        "    at __require (/var/task/index.js:12:51)",
        "    at node_modules/aws-crt/dist/native/auth.js (/var/task/index.js:781569:38)",
        "    at __require (/var/task/index.js:12:51)",
        "    at node_modules/aws-crt/dist/index.js (/var/task/index.js:785169:30)",
        "    at __require (/var/task/index.js:12:51)",
        "    at node_modules/@aws-sdk/signature-v4-crt/dist-cjs/CrtSignerV4.js (/var/task/index.js:981809:21)",
        "    at __require (/var/task/index.js:12:51)",
        "    at node_modules/@aws-sdk/signature-v4-crt/dist-cjs/index.js (/var/task/index.js:981939:25)",
        "    at __require (/var/task/index.js:12:51)"

Reproduction Steps

  1. Install @aws-sdk/signature-v4-crt
  2. use signature-v4-crt for exmaple:

    const sigV4 = new CrtSignerV4({
      credentials: options.sigv4.credentials,
      region: '*', 
      service: options.sigv4.service,
      sha256: Sha256
    })
    
    const { method, headers, body } = await sigV4.sign(
      {
        method: requestInit.method,
        headers: requestInit.headers,
        protocol: 'https',
        hostname: url.hostname,
        path: `${url.pathname}?${url.search}`,
        body: requestInit.body as string | undefined,
      },
    )
  3. Deploy code in a lambda function to Node18 runtime
  4. execute and it fails with the error above.

Possible Solution

No response

Additional Information/Context

No response

aws-crt-nodejs version used

1.18.3

nodejs version used

18

Operating System and version

linux2

justin-masse commented 10 months ago

My gut feeling is this has something to do with this code in binding.js --

let binding;
for (const path of search_paths) {
    if ((0, fs_1.existsSync)(path + '.node')) {
        binding = require(path);
        break;
    }
}

but i'm working on verifying that by giving require() a direct path to the binary in my lambda. This will possibly confirm that this is broken when the node module gets hoisted out of signature-v4-crt and into root.

bretambrose commented 10 months ago

Somewhat relevant: https://github.com/awslabs/aws-crt-nodejs/pull/490

justin-masse commented 10 months ago

Somewhat relevant: #490

yeah, something like that might work. I am having trouble getting the path because process.cwd() is /var/task on lambda so i'm going to try to force the aws-crt pkg binary into where it is "expected" and see if that works.

It might be worthwhile for the sigv4-crt package to just include the binaries as well but that seems like overkill.

justin-masse commented 10 months ago

This also appears to be happening on my lambda when using the implementation with just aws-crt and running crt.auth.sign()

justin-masse commented 8 months ago

So just wanted to reiterate the problem here, this is a problem with the relative pathing to the nodejs binaries within the aws-crt package. This breaks when using esbuild/webpack.

I was able to workaround this by doing the following:

  1. add aws-crt as a layer to all of my lambdas
  2. add --external:aws-crt to my esbuild command so it would reference the code in the lambda layer that was not being built with webpack/esbuild.

This is a very annoying process to have to update our lambdas to use aws-crt as a layer instead of being able to bake it in with the multi-region signing npm package on top of having to update all of our services to mark it as an external package within esbuild.

justin-masse commented 5 months ago

Any update? Will this support webpack/esbuild anytime soon?

jmklix commented 6 days ago

This issue will be made irrelevant by this pr, as sigv4 would the be supported natively by the js sdk.