This article talks about a way to package multiple Lambda functions into a npm module. The module is deployed as an AWS Lambda layer, and function are required from the layer.

In an AWS ecosystem, Lambda fns form the foundation of server-less architecture or Function as a Service (FaaS).  Server-less does not mean there are no servers involved, but one don't provision or manage the servers on which the functions execute. This arrangement makes sense for many workloads.

JavaScript (NodeJs) is one of the many programming environments supported in AWS Lambda. The NodeJs lambda functions can be developed right in the AWS Console for simple cases. In typical development cycle, the functions are developed and tested in development environments and deployed to AWS.

The template below is a way to develop and package a node module, that can be easily deployed to AWS. AWS layer requires us to upload a zip with all dependencies (node_modules/*). So we don't get a chance to run npm install in AWS.

The trick here is to create a local npm module that can be installed locally using npm pack. Then we go on to create a new empty npm module (npm init) and install the package we just created. This will install our module along with its dependencies in node_modules folder. Zip the new module starting from root and it is ready for upload to AWS Lambda.

lambdas
  - lib
    - fn1
      - index.js
    - fn2
      - index.js
  - test
    - fn1
      - fn1.test.js
  - .eslintrc
  - awszip.sh
  - index.js
  - package.json
  - README.md
folder structure
// index.js
module.exports = {
    fn1: require('./lib/fn1/index'),
    fn2: require('./lib/fn2/index')
};
index.js
//lib/fn1/index.js
module.exports = {
    fn1: function() {
    }
};
fn1
//package.json
{
  "name": "lambdas",
  "version": "0.1.0",
  "description": "AWS Lambda Functions",
  "main": "index.js",
  "dependencies": {
    "__comment": "dependencies of the fns",
    "lodash": "4.17.15",
    "request": "2.88.0",
    "aws-sdk": "2.553.0",
    "request-promise-native": "1.0.7"
  },
  "devDependencies": {
    "mocha": "6.2.2",
    "chai": "4.2.0",
    "eslint": "6.5.1"
  },
  "scripts": {
    "test": "./node_modules/.bin/mocha --reporter spec",
    "awszip": "bash awszip.sh"
  },
  "author": "vijay konnackal",
  "license": "UNLICENSED",
  "private": true,
  "repository": ""
}
package.json

#!/usr/bin/env bash

rm -rf *.tgz
rm -rf build
npm pack

mkdir -p build
rm -rf build/*

cd build

npm init -y
npm i ../lambdas*.tgz

mkdir nodejs
mv node_modules nodejs/
7z a -tzip lambdas.zip nodejs
awszip.sh

Now in AWS start creating the functions. Lambda fn1 will be a single liner.

exports.handler = require('lambdas').fn1;