Serverless and npm native modules
How to compile your native npm packages for the AWS Serverless image.
Like all good days in software development- today has been a fun day of putting out fires. That doesn’t mean that there wasn’t time to learn something, however. And today’s small lesson was on deploying lambda functions with native modules.
Thanks to the fantastic work of the Serverless Framework people, writing and deploying AWS lambda functions is mostly a breeze. It’s not perfect, however, and while desperately fighting to get a trial fix out, I discovered that node/npm modules with native extensions (and there’s a surprisingly large amount of them out there) are not your friend.
You see, the Serverless Framework (just like the AWS documentation says you should) simply zips-up all your code and modules and dispatches them.
Unfortunately this means that unless you happen to be working on an Amazon Linux machine, your native modules will be built for a completely different architecture, and you’ll see this lovely error:
invalid ELF header.
There’s a few solutions out there- obviously a full CD environment based on the target architecture is ideal, but for when you just-need-something-local, you can always use a Docker container. And to save you some time, here’s mine:
First build it:
docker build --pull -t sls-amazonlinux:latest .
Then run it:
docker run --rm -it -v $HOME/.aws:/root/.aws -v $PWD:/src -v $PWD/.tmp/node_modules:/src/node_modules sls-amazonlinux:latest
Note the three volumes: The first
$HOME/.aws:/root/.aws is used to pull in your AWS credentials, the next
$PWD:/src gives you access to your source code, and the last (optional)
$PWD/.tmp/node_modules:/src/node_modules saves you having to download your project modules every time.
Then you can build and deploy like you would on your own machine:
./node_modules/.bin/serverless deploy -v
Anyway- hopefully that’ll be useful to someone else!