Creating a node module for aws lambda
I'm trying to use the Sharp library in AWS Lambda, but it requires the module to be compiled for the lambda environment. The instructions say to create an instance of ec2 and compile it there, but I noticed there are several tools to help with this, but they are all at least a year out of service. Is there a package that comes with Serverless, or something that counts as a standard way?
I found them, but they are all at least a year since commit
https://github.com/node-hocus-pocus/thaumaturgy
https://github.com/Max-Kolodezniy/aws-lambda-build
https://github.com/tomdale/lambda-packager
Maybe there is a directory somewhere where I can just download the pre-compiled Sharp library for AWS lambda?
source to share
I did this with the sharp-0.17.3-aws-linux-x64-node-6.10.1.tar.gz tarball that was built on an AWS EC2 instance with Nodejs 6.10.1 . The tarball contains a directory node_modules/
with sharp
system binaries (libvips library) specific to the Lambda runtime .
Project structure
To avoid conflicts between local node_modules/
(Nodejs 7.5 on Mac) and node_modules/
inside the tarball (Nodejs 6.10 on Linux), I create my Lambda service in a subdirectory.
The project structure looks like this:
node_modules/
service/
node_modules/ <= sharp-0.17.3-aws-linux-x64-node-6.10.1.tar.gz
utils/
handler.js
package.json <= engines: node 6.10.1
serverless.yml
src/
jasmine.json
package.json
Most of the dependencies I need are for development and testing. They are maintained inside the root file package.json
(also includes sharp
, but compiled for my Nodejs 7.5 environment, suggesting testing images locally).
My service/handler.js
and service/utils/
contains ES6 compatible source code with a Lambda function handler - it is translated from the directory src/
.
If I need other dependencies for production (besides sharp
), I install them services/package.json
using the option --prefix
. But no aws-lambda
, no aws-sdk
- they are globally installed inside Lambda, which means they don't need to be included in the deployment file .zip
.
npm i -S lodash --prefix services/
It ensures lodash
that a Lambda-compatible service/package.json
version is installed because it defines the Nodejs version you can rely on:
{
"private": true,
"engines": { "node" : "6.10.1" },
"dependencies": {
...
}
}
However, there is a caveat - other production dependencies should not be dependent on the environment. If so, they won't work because you are installing them from your local machine, which is not equal to Lambda.
Expanding lambda functions
Since Lambda requires an archive .zip
, I compress the contents of my directory service/
. And my Lambda functions are working. Everything is ES6 compliant, sharp
has Lambda binaries, and my other versions of dependencies in production relate to Nodejs 6.10.1.
Also, I would suggest using Serverless ⚡️ (I use it too). This makes developing and deploying lambda functions much easier.
source to share
Nick's answer definitely helped me get to a working solution! One thing I would add is that people without a server-side sharp image have updated their package, so the tarball works with node v6.10 now, so I see no reason to have two different node environments referenced. I am doing everything in v6.10.
https://github.com/adieuadieu/serverless-sharp-image/tree/master/lib
source to share