Myrmex Home Reference Source Repository
Manual » Usage

Lambda plugin

The @myrmex/lambda plugin allows to define and deploy Lambdas. It should work with any runtime but has been tested mostly with Node.js and secondly with Python.

Prerequisites

To use the @myrmex/lambda plugin, it is necessary to have a minimal knowledge about AWS Lambda.

An AWS user or role that uses the plugin @myrmex/lambda must have access to Lambda administration. The AWS policy AWSLambdaFullAccess gives all necessary permissions.

Installation

Install the npm module in a Myrmex project:

npm install @myrmex/lambda

Then enable the plugin in the myrmex.json file:

{
  "name": "my-app",
  "plugins": [
    "@myrmex/lambda"
  ]
}

Once the plugin is installed and enabled in the project, the myrmex command line will provide new sub-commands to manage and deploy Lambdas.

Project anatomy

By default, the content managed by the Lambda plugin is located in an lambda directory in the root directory of the project.

Out of the box, for the Node.js runtime, the Lambda plugin allows to separate the definition of Lambdas from the logic of the application by providing a specific place to write node modules but it is not mandatory to use it. @myrmex/lambda helps to define and deploy Lambdas but the developer is responsible of the implementation of the application. Other plugins built on top of the Lambda plugin may be more opinionated.

The directory lambda/lambdas contains the Lambdas definitions. For each of its sub-directory is considered as a Lambda definition. It must contains a config.json file and the code of the Lambda. The name of the subdirectory is used as the Lambda identifier.

The config.json file allows to define the runtime, the timeout, the memory, the role and other properties of the Lambda. The content of the params property is used as the argument of the following methods from the AWS SDK:

Example of config.json file:

{
  "params": {
    "Timeout": 10,
    "MemorySize": "256",
    "Runtime": "nodejs6.10",
    "Handler": "index.handler",
    "Role": "arn:aws:iam::012345678901:role/LambdaBasicExecution"
  }
}

By default, for the Node.js runtime, the directory lambda/modules contains the node modules of the project. For example, some of these modules could be named log, or data-access or authorization etc...

Each module should have a clear responsibility so that each Lambda can embed only the code it needs. This is a recommendation but the developer is free to organize the code as he want. The Lambda plugin does not force you to use a specific project organization.

This is what a project structure could look like:

lambda
├── lambdas                         The Lambdas defined by the application
|   ├── my-nodejs-lambda            The name of this directory is the identifier of a Lambda
|   |   ├── config.json             The configuration of the Lambda (runtime, memory, timeout, execution role...)
|   |   ├── index.js                A node module that exposes the handler
|   |   └── package.json            It is possible to install the dependencies of the Lambda here
|   └── my-python-lambda            Several runtimes can coexist in a project
|       ├── config.json
|       └── lambda_function.py
└── modules                         The node modules of the application - they can be added as a dependency of a Lambda in its
    |                               package.json file
    ├── authorization               The name of this directory is the identifier of a module
    |   ├── package.json            Package file of the module
    |   ├── index.js                Main file of the module
    |   └── test                    If you wish, you can write the code to test the module in this directory
    ├── data-access
    |   ├── package.json
    |   └── index.js
    └── log
        ├── package.json
        └── index.js

Example of config.json file:

{
  "params": {
    "Timeout": 30,
    "MemorySize": 256,
    "Role": "arn:aws:iam::123456789012:role/MyRole",
    "Runtime": "nodejs6.10",
    "Handler": "index.handler"
  }
}

The package.json of a module or a Lambda can declare dependencies with other modules using file paths in the dependencies property:

{
  "name": "data-access",
  "version": "0.0.0",
  "dependencies": {
    "log": "../log"
  }
}

In this case, require('log') will load the module log installed in lambda/modules/data-access/node_modules/log.

It is recommended to use relative paths for portability.

It is recommended to use a recent version of npm to minimize the size of the Lambda packages and facilitate the configuration of nested dependencies. Indeed, npm@2 can behave in an unexpected manner with nested dependencies when using relative file paths.

Configuration

These are Myrmex configuration keys specific to to the @myrmex/lambda plugin.

Default values

Using myrmex show-config after installing the plugin, we can see the default configuration:

{
  "lambda": {
    "lambdasPath": "lambda/lambdas",
    "modulesPath": "lambda/modules"
  }
}

lambda.lambdasPath

Path to the folder that contains Lambdas. Default value: lambda/lambdas.

lambda.modulesPath

Path to the folder that contains modules for Node.js Lambdas. Default value: lambda/modules.

lambda.alias

Set the alias applied when deploying Lambdas.

By setting this configuration, the --alias option of the myrmex deploy-lambdas command does not prompt when not provided via the command line and the configured value is used as the default value.

Setting lambda.alias to an empty string disables the creation/update of an alias and the new version of the Lambda will only be available as LATEST.

Example

Using the myrmex.json file, the plugin configuration can be defined like this:

{
  "name": "A Myrmex project",
  "plugins": [
    "@myrmex/lambda"
  ],
  "config": {
    "lambda": {
      "lambdasPath": "lambdas",
      "modulesPath": "modules",
      "alias": ""
    }
  }
}

Commands

create-lambda

create-lambda [options] [identifier]

  Options:
    -r, --runtime <nodejs|nodejs4.3|nodejs6.10|python2.7|python3.6>  select the runtime
    -t, --timeout <timeout>                                          select the timeout (in seconds)
    -m, --memory <memory>                                            select the memory (in MB)
    -d --dependencies <modules-names>                                select the project modules that must be included in the Lambda (only for nodejs runtimes)
    --role <role>                                                    select the execution role (enter the ARN)

Create a new Lambda. By default the location of Lambdas is lambda/lambdas/<identifier>/.

create-node-module

For the Node.js runtime only.

create-node-module [options] [name]

  Options:
    -d, --dependencies <dependent-modules>  select the node modules that are dependencies of this new one

Prepare a new Node.js module. By default the location of modules is lambda/modules/<name>/.

The creation of nodes modules is just a suggestion to organize the code of a project. The idea is to maintain each component of the application in its own node module to select only relevant components when deploying Lambdas.

Every Lambda can declare its modules dependencies using local paths in its package.json file. Every module can also declare dependencies to other modules that way.

When Myrmex deploys a Lambda, it executes npm install and the dependencies are installed in the node_modules folder.

deploy-lambdas

deploy-lambdas [options] [lambda-identifiers...]

  Options:
    --all                            deploy all lambdas of the project
    -r, --region <region>            select the AWS region
    -e, --environment <environment>  select the environment
    -a, --alias <alias>              select the alias to apply

Deploy one or more Lambdas in AWS. The --environment option is used as a prefix. The --alias option will publish a version in Amazon Lambda and apply an alias. Setting the option to an empty string (--alias "") will skip this.

When deploying Node.js Lambdas, it is recommended to use npm4 to optimize the size of the packages and avoid the resolution of local dependencies with symbolic links (behavior of npm5).

When deploying Lambdas with C/C++ bindings and/or to be sure to create packages with the correct runtime, use the plugin @myrmex/packager

install-lambdas-locally

install-lambdas-locally [lambda-identifiers...]

Deletes the node_modules folder of one or several lambda and runs npm install to re-install it.

test-lambda-locally

test-lambda-locally [options] [lambda-identifier]

  Options:
    -e, --event <event-name>  Event example to use

Executes a Lambda locally. The event option allows to select the example object that will be passed as the first argument. Example objects are defined in json files in lambda/lambdas/<identifier>/events/<event-name>.json. A mock of the conshell object is passed as the second argument.

test-lambda

test-lambda [options] [lambda-identifier]

  Options:
    --event <event-name>             Event example to use
    -r, --region <region>            select the AWS region
    -e, --environment <environment>  select the environment
    -a, --alias <alias>              select the alias to test

Executes a Lambda deployed in AWS. The event option allows to select the example object that will be passed as the first argument. Example objects are defined in json files in lambda/lambdas/<identifier>/events/<event-name>.json. A mock of the conshell object is passed as the second argument.

Setting the option --alias to an empty string (--alias "") will invoke the LATEST version of the Lambda.

Integration with @myrmex/api-gateway

@myrmex/lambda add some functionalities to @myrmex/api-gateway when both are installed in the same project.

Associate a Lambda with an API endpoint

In the spec.json file that describes an endpoint, a new extension to Swagger is available to select a Lambda that must be used for the endpoint integration.

{
  "x-myrmex": {
    "apis": [],
    "lambda": "lambda-identifier"
  }
  ... rest of the endpoint specification
}

New option for myrmex create-endpoint

When calling myrmex create-endpoint, a new option --lambda <lambda-identifier> is available. This option accepts the identifier of a Lambda managed by @myrmex/lambda.

If the option is not provided in the command line and the option --integration is set to lambda or lambda-proxy, a prompt will propose to select the appropriate Lambda in a list.

The value of --lambda <lambda-identifier> will be set in extension to Swagger described above.

New options for myrmex deploy-apis

When calling myrmex create-endpoint, two new options are available:

--deploy-lambdas <all|partial|none>

The option --deploy-lambdas <all|partial|none> accepts three possible values:

  • all will perform the deployment of all Lambdas defined in the Myrmex project before deploying the APIs.
  • partial will perform the deployment of all Lambdas that are associated to deployed endpoints before deploying the APIs.
  • none will not deploy any Lambda, but it will retrieve the ARNs of all Lambdas that are associated to deployed endpoints. So these Lambda have to be already deployed with the appropriate alias.

--alias <alias>

The option --alias <alias> allows to select the Lambda alias that will be integrated with endpoints.

If the lambda.alias configuration is set and the option is not provided via the command line, no prompt will appear to set the value the configured value is used as the default value.