Creating a Deployment Package (Node.js) describes how to create a compressed payload that includes the node_modules folder for Lambda functions that require npm modules.

An alternative to including the entire node_modules folder in the payload is to use webpack to bundle the Lambda function code and it’s dependencies into a single file.

Example

  • build
  • node_modules
    • async
    • aws-sdk
  • src
    • doStuff.js
  • webpack.config.js

src/doStuff.js

1
2
3
4
5
6
7
8
const aws = require('aws-sdk');
const async = require('async');

function handler(event, context, callback) {
    // Do stuff with async and callback
}

exports.handler = handler;

webpack.config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const path = require('path');

const SRC_DIR = path.resolve(__dirname, 'src');
const OUT_DIR = path.resolve(__dirname, 'build');

const config = {
    entry: {
        doStuff: path.resolve(SRC_DIR, 'doStuff.js')
    },
    // aws-sdk is already available in the Node.js Lambda environment
    //  so it should not be included in function bundles
    externals: [
        'aws-sdk'
    ],
    output: {
        path: OUT_DIR,
        filename: '[name].js',
        library: '[name]',
        libraryTarget: 'umd'
    },
    target: 'node'
};

module.exports = config;

Define one entry per Lambda function. The functions are bundled as umd libraries so that they can be loaded by the Node.js Lambda environment.

Running the webpack command will output the bundle(s) to the build folder.

If the function is being deployed with Terraform, the Archive Provider can be used to automatically create a compressed version of the bundle that can be referenced in the aws_lambda_function definition:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
variable fn_dostuff_name {
  default = "doStuff"
}

# Create a payload zip file from the function source code bundle
data "archive_file" "af_dostuff" {
  type = "zip"
  source_file = "build/${var.fn_dostuff_name}.js"
  output_path = "build/${var.fn_dostuff_name}.zip"
}

# Define the Lambda function
resource "aws_lambda_function" "fn_dostuff" {
  runtime = "nodejs6.10"
  function_name = "${var.fn_dostuff_name}"
  handler = "${var.fn_dostuff_name}.handler"
  filename = "${data.archive_file.af_dostuff.output_path}"
  source_code_hash = "${base64sha256(file("${data.archive_file.af_dostuff.output_path}"))}"
  role = "${aws_iam_role.example_lambda_role.arn}"
}

Note: aws_iam_role.example_lambda_role definition is omitted for clarity. See react-terraform-starter-kit/service/role_lambda.tf for an example.