23

I have based a small lambda function off the cdk workshop here. I'm writing the lambda function in typescript, deploying via a pipeline which creates a cloud formation stack containing the lambda function.

I'm trying to use the sdk v3 in lambda, as demoed here. But then I see conflicting documentation here.

Are these errors because I'm trying to use V3 and I shouldn't, or for some other reason? The handler is set correctly, the function runs but fails with the error:

{ "errorType": "Runtime.ImportModuleError", "errorMessage": "Error: Cannot find module '@aws-sdk/client-sns'\nRequire stack:\n- /var/task/ReceiveMessageLoraThing.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js", "stack": [ "Runtime.ImportModuleError: Error: Cannot find module '@aws-sdk/client-sns'", "Require stack:", "- /var/task/ReceiveMessageLoraThing.js", "- /var/runtime/UserFunction.js", "- /var/runtime/index.js", " at _loadUserApp (/var/runtime/UserFunction.js:100:13)", " at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)", " at Object.<anonymous> (/var/runtime/index.js:43:30)", " at Module._compile (internal/modules/cjs/loader.js:999:30)", " at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)", " at Module.load (internal/modules/cjs/loader.js:863:32)", " at Function.Module._load (internal/modules/cjs/loader.js:708:14)", " at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)", " at internal/main/run_main_module.js:17:47" ] } 

The file is deployed as js, with the correct handler set. If I comment out the require statement, it works fine:

// works "use strict"; //const sns = require("@aws-sdk/client-sns"); exports.handler = async (event) => { console.log("hello"); return true; } // doesn't work "use strict"; const sns = require("@aws-sdk/client-sns"); exports.handler = async (event) => { console.log("hello"); return true; } 

There are no node_modules or layers generated by using the code from this workshop, but before I go there I want to know if I can actually use V3 on lambda yet.

2
  • 1
    FWIW you can inspect what's in an AWS Lambda runtime by doing docker run --rm -it --entrypoint /bin/bash amazon/aws-lambda-nodejs[:version]. The pre-installed packages available in the Node 14 version are in /var/runtime/node_modules, which contains only aws-sdk. Commented Dec 1, 2021 at 2:18
  • There are also packages npm depends on in /var/lang/lib/node_modules/npm/node_modules, but you can't require them by name from your handler, and it would probably be a bad idea to rely on them Commented Dec 1, 2021 at 2:20

1 Answer 1

30

Yes, you can use AWS SDK v3, just like any other JS library.

The Node environment for Lambda comes with installed AWS SDK v2 (the previous one), as you can see here: https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html

So to use v3, you should bundle it with your application as with any other dependency, and deploy the bundle (https://docs.aws.amazon.com/lambda/latest/dg/nodejs-package.html).

Actually, even with SDK v2 being available on the Lambda env, it was still a best practice to bundle it by yourself with your app and deploy it. This way you would always use the version you specified, and not the one that is on Lambda and can be updated any time. Even if they do not make any incompatible changes, it's always possible that the new SDK version, not tested with your specific app, will have some bug that will break your Lambda (very unlikely, but possible).

Edit (2022-11-22): Node.js 18 Lambda runtime includes SDK v3 and does not include v2 (https://aws.amazon.com/blogs/compute/node-js-18-x-runtime-now-available-in-aws-lambda/).

Sign up to request clarification or add additional context in comments.

11 Comments

I did not use CDK (only Serverless Framework) so I don't know how this exactly works, but I don't see a reason to multiply node_modules. It should be possible to create multiple functions in single project.
@JHH agree and as they want to use sdk v3 they are going to include them one way or another. I suggest they provide them to their lambda in an isolated layer and not bundle together with rest of module deps. In a separate layer they may share with other lambdas and when v3 is provided out of the box OP can either drop the layer or continue maintain specific v3 version themselves.
Is there any reason they do not include the aws-sdk v3 as a acpkage the same way they do it with v2?
The downside of always deploying a specific SDK version via layer, or otherwise, is that you lose the benefit of the AWS Lambda service auto updating the SDK dependency for you. That's a potential no-cost security benefit whose value needs to be weighed against the risk of a breaking change in the SDK.
@zrkl, AWS seem to have gone to a lot of trouble in v3 to separate out all their packages. They've always advised people to bundle up a specific SDK version rather than relying on the lambda runtime version. I'd imagine they might be intentionally not exposing v3 so that people follow this advice; afterall I'm sure it would be fairly trivial for them to just bake v3 into the lambda runtime e.g. with a Docker build. As for v2, they probably have to leave that in there for backwards compatibility. I may be wrong, maybe v3 will be part of the runtime in future, but I'm not holding my breath.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.