# grunt-aws-lambda

> A grunt plugin to help develop AWS Lambda functions.

Latest version **0.13.0** (published 2016-05-31) · 0 weekly downloads

## Install

```sh
npm install grunt-aws-lambda
pnpm add grunt-aws-lambda
yarn add grunt-aws-lambda
bun add grunt-aws-lambda
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.13.0 |
| Published | 2016-05-31 |
| First published | 2014-11-30 |
| Weekly downloads | 0 |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >= 0.8.0 |
| Dependencies | 9 |
| Known vulnerabilities | 0 (+7 in 2 direct dependencies) |
| Install scripts | no |
| GitHub stars | 243 |
| Author | Tim-B |
| Maintainers | tim-b |
| Keywords | gruntplugin |

## Links

- npm: https://www.npmjs.com/package/grunt-aws-lambda
- Repository: https://github.com/Tim-B/grunt-aws-lambda
- Issues: https://github.com/Tim-B/grunt-aws-lambda/issues
- npm.io page: https://npm.io/package/grunt-aws-lambda

## Dependencies (9)

- [q](https://npm.io/package/q.md) ^1.4.1
- [npm](https://npm.io/package/npm.md) ^2.10.0
- [glob](https://npm.io/package/glob.md) ~4.3.0
- [mkdirp](https://npm.io/package/mkdirp.md) ~0.5.0
- [rimraf](https://npm.io/package/rimraf.md) ~2.2.8
- [aws-sdk](https://npm.io/package/aws-sdk.md) ~2.2.32
- [archiver](https://npm.io/package/archiver.md) ~0.14.4
- [temporary](https://npm.io/package/temporary.md) ~0.0.8
- [proxy-agent](https://npm.io/package/proxy-agent.md) latest

## Recent versions

- 0.13.0 (latest) — 2016-05-31
- 0.12.0 — 2016-02-15
- 0.11.0 — 2015-11-03
- 0.10.0 — 2015-08-01
- 0.9.0 — 2015-07-24
- 0.8.0 — 2015-07-12
- 0.7.0 — 2015-06-28
- 0.6.0 — 2015-06-28
- 0.5.0 — 2015-06-28
- 0.4.0 — 2015-05-23
- 0.3.0 — 2014-12-19
- 0.2.0 — 2014-12-02
- 0.1.0 — 2014-11-30

## README

# grunt-aws-lambda

> A grunt plugin to assist in developing functions for [AWS Lambda](http://aws.amazon.com/lambda/).

[![Build Status](https://travis-ci.org/Tim-B/grunt-aws-lambda.svg)](https://travis-ci.org/Tim-B/grunt-aws-lambda)

This plugin provides helpers for:
* Running Lambda functions locally
* Managing npm dependencies which are required by your function
* Packaging required dependencies with your function in a Lambda compatible zip
* Uploading package to Lambda

## Getting Started
This plugin requires Grunt `~0.4.5`

If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

```shell
npm install grunt-aws-lambda --save-dev
```

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

```js
grunt.loadNpmTasks('grunt-aws-lambda');
```

## Gotchas

### Add dist to your .npmignore

This will save you from packaging previous packages in future ones.

For example your `.npmignore` might look something like this:
```
event.json
Gruntfile.js
dist
*.iml
```

[Read More](#default-options-1)

## Authenticating to AWS

This library supports providing credentials for AWS via an IAM Role, an AWS CLI profile, environment variables, a JSON file on disk, or passed in credentials.
To learn more, please see the [below section](#aws-credentials)

## grunt-aws-lambda tasks

### Overview

This plugin contains 3 tasks:
* lambda_invoke - Wrapper to run and test lambda functions locally and view output.
* lambda_package - Packages function along with any npm dependencies in a zip format suitable for lambda.
* lambda_deploy - Uploads the zip package to lambda.

lambda_invoke and lambda_package can be used independently, lambda_deploy will invoke lambda_package before uploading
the produced zip file.

### lambda_invoke

In your project's Gruntfile, add a section named `lambda_invoke` to the data object passed into `grunt.initConfig()`.

```js
grunt.initConfig({
    lambda_invoke: {
        default: {
            options: {
                // Task-specific options go here.
            }
        }
    },
});
```

#### Options

##### options.handler
Type: `String`
Default value: `handler`

Name of the handler function to invoke.

##### options.file_name
Type: `String`
Default value: `index.js`

Name of your script file which contains your handler function.

##### options.event
Type: `String`
Default value: `event.json`

Name of the .json file containing your test event relative to your Gruntfile.

#### Usage Examples

##### Default Options
In this example, the default options are used therefore if we have the following in our `Gruntfile.js`:

```js
grunt.initConfig({
    lambda_invoke: {
        default: {
            options: {
                // Task-specific options go here.
            }
        }
    },
});
```
And the following in `index.js`

```js
exports.handler = function (event, context) {
    console.log('value1 = ' + event.key1);
    console.log('value2 = ' + event.key2);
    console.log('value3 = ' + event.key3);

    context.done(null, 'Hello World');  // SUCCESS with message
};
```

And the following in `event.json`
```json
{
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
}
```

Then we run `grunt lambda_invoke`, we should get the following output:

```
Running "lambda_invoke" task

value1 = value1
value2 = value2
value3 = value3

Message
-------
Hello World

Done, without errors.
```


### lambda_package

This task generates a lambda package including npm dependencies using the default npm install functionality.

In your project's Gruntfile, add a section named `lambda_package` to the data object passed into `grunt.initConfig()`.

```js
grunt.initConfig({
    lambda_package: {
        default: {
            options: {
                // Task-specific options go here.
            }
        }
    },
});
```

#### Options

##### options.include_files
Type: `Array`
Default value: `[]`

List of files to explicitly include in the package, even if they would be ignored by NPM

##### options.include_time
Type: `Boolean`
Default value: `true`

Whether or not to timestamp the packages, if set to true the current date/time will be included in the zip name, if false
 then the package name will be constant and consist of just the package name and version.

##### options.include_version
Type: `Boolean`
Default value: `true`

Whether or not to include the NPM package version in the artifact package name. Set to false if you'd prefer a static
 package file name regardless of the version.

##### options.package_folder
Type: `String`
Default value: `./`

The path to your npm package, must contain the package.json file.

##### options.dist_folder
Type: `String`
Default value: `dist`

The folder where the complete zip files should be saved relative to the Gruntfile.

#### Usage Examples

##### Default Options
In this example, the default options are used therefore if we have the following in our `Gruntfile.js`:

```js
grunt.initConfig({
    lambda_package: {
        default: {
            options: {
                // Task-specific options go here.
            }
        }
    },
});
```
And the following in `package.json`

```json
{
    "name": "my-lambda-function",
    "description": "An Example Lamda Function",
    "version": "0.0.1",
    "private": "true",
    "dependencies": {
        "jquery": "2.1.1"
    },
    "devDependencies": {
        "grunt": "0.4.*",
        "grunt-pack": "0.1.*",
        "grunt-aws-lambda": "0.1.*"
    }
}
```

Then we run `grunt lambda_package`, we should see a new zip file in a new folder called `dist` called something like:

`my-lambda-function_0-0-1_2014-10-30-18-29-4.zip`

If you unzip that and look inside you should see something like:
```
index.js
package.json
node_modules/
node_modules/jquery
node_modules/jquery/... etc
```

Given that by default the dist folder is inside your function folder you can easily end up bundling previous packages
 inside subsequent packages therefore it is **strongly advised that you add dist to your .npmignore**.

For example your `.npmignore` might look something like this:
```
event.json
Gruntfile.js
dist
*.iml
```

### lambda_deploy

In your project's Gruntfile, add a section named `lambda_deploy` to the data object passed into `grunt.initConfig()`.

```js
grunt.initConfig({
    lambda_deploy: {
        default: {
            arn: 'arn:aws:lambda:us-east-1:123456781234:function:my-function',
            options: {
                // Task-specific options go here.
            }
        }
    },
});
```

#### Options


##### arn
Type: `String`
Default value: None - Required

The ARN of your target Lambda function.

##### function
Type: `String`
Default value: None - Required (if you havn't specified an ARN)

*This option is deprecated, use arn instead*. The name of your target Lambda function, ie. the name of the function in the AWS console.

##### Proxy
On Linux based hosts you can set proxy server for deploy task by specifying standard environment variable - https_proxy.
E.g: 
env https_proxy=http://localhost:8080 grunt deploy

##### package
Type: `String`
Default value: Package name set by package task of same target - see below.

The name of the package to be uploaded.

When the lambda_package task runs it sets the package value for the lambda_deploy target with the same name.

Therefore if lambda_package and lambda_deploy have a target (eg. default) with the same name you will not
 need to provide this value - it will be passed automatically.

For example, your Gruntfile.js might contain the following:


```js
grunt.initConfig({
    lambda_deploy: {
        default: {
            arn: 'arn:aws:lambda:us-east-1:123456781234:function:my-function'
        }
    },
    lambda_package: {
        default: {
        }
    }
});
```

You could then run `grunt lambda_package lambda_deploy` and it'll automatically create the package and deploy it without
 having to specify a package name.

##### options.profile
Type: `String`
Default value: `null`

If you wish to use a specific AWS credentials profile you can specify it here, otherwise it will use the environment default.
You can also specify it with the environment variable `AWS_PROFILE`

##### options.RoleArn
Type: `String`
Default value: `null`

If you wish to assume a specific role from an EC2 instance you can specify it here, otherwise it will use the environment default.

##### options.accessKeyId
Type: `String`
Default value: `null`

If you wish to use hardcoded AWS credentials you should specify the Access Key ID here

##### options.secretAccessKey
Type: `String`
Default value: `null`

If you wish to use hardcoded AWS credentials you should specify the Secret Access Key here

##### options.credentialsJSON
Type: `String`
Default value: `null`

If you wish to use hardcoded AWS credentials saved in a JSON file, put the path to the JSON here. The JSON must conform to the [AWS format](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html#Credentials_from_Disk).

##### options.region
Type: `String`
Default value: `us-east-1`

Specify the AWS region your functions will be uploaded to. Note that if an ARN is supplied this option is not required.

##### options.timeout
Type: `Integer`
Default value: `null`
Depending on your Lambda function, you might need to increase the timeout value. The default timeout assigned by AWS is currently 3 seconds.
If you wish to increase this timeout set the value here.

##### options.memory
Type: `Integer`
Default value: `null`

Sets the memory assigned to the function. If null then the current setting for the function will be used. Value is in MB and must be a multiple of 64.

##### options.handler
Type: `String`
Default value: `null`

Sets the handler for your lambda function. If left null, the current setting will remain unchanged.

##### options.enableVersioning
Type: `boolean`
Default value: `false`

When enabled each deployment creates a new version.

##### options.aliases
Type: `String` or `Array`
Default value: `null`

If a string or an array of strings then creates these aliases. If versioning enabled then points to the created version,
otherwise points to `$LATEST`.

It is recommended that `enableVersioning` is also enabled when using this feature.

Examples:

Creates one `beta` alias:
```js
aliases: 'beta'
```

Creates two aliases, `alias1` and `alias2`:
```js
aliases: [
    'alias1',
    'alias2'
]
```

##### options.enablePackageVersionAlias
Type: `boolean`
Default value: false

When enabled creates a second alias using the NPM package version. When the NPM package version is bumped a new
alias will be created, allowing you to keep the old alias available for backward compatibility.

It is recommended that `enableVersioning` is also enabled when using this feature.

##### options.subnetIds
Type: `Array`
Default value: `null`

A list of one or more subnet IDs in your VPC.

##### options.securityGroupIds
Type: `Array`
Default value: `null`

A list of one or more security groups IDs in your VPC.

If your Lambda function accesses resources in a VPC you must provide at least one security group and one subnet ID. These must belong to the same VPC

#### Usage Examples

##### Default Options
In this example, the default options are used therefore if we have the following in our `Gruntfile.js`:

```js
grunt.initConfig({
    lambda_deploy: {
        default: {
            arn: 'arn:aws:lambda:us-east-1:123456781234:function:my-function'
        }
    }
});
```
And now if you run `grunt lambda_deploy` your package should be created and uploaded to the specified function.


##### Increasing the Timeout Options to 10 seconds
In this example, the timeout value is increased to 10 seconds and set memory to 256mb.

```js
grunt.initConfig({
    lambda_deploy: {
        default: {
            arn: 'arn:aws:lambda:us-east-1:123456781234:function:my-function',
            options: {
                timeout : 10,
                memory: 256
            }
        }
    }
});
```

##### Example with a beta and prod deployment configuration

Deploy to beta with `deploy` and to prod with `deploy_prod`:

```js
grunt.initConfig({
    lambda_invoke: {
        default: {
        }
    },
    lambda_deploy: {
        default: {
            options: {
                aliases: 'beta',
                enableVersioning: true
            },
            arn: 'arn:aws:lambda:us-east-1:123456789123:function:myfunction'
        },
        prod: {
            options: {
                aliases: 'prod',
                enableVersioning: true
            },
            arn: 'arn:aws:lambda:us-east-1:123456789123:function:myfunction'
        }
    },
    lambda_package: {
        default: {
        },
        prod: {
        }
    }
});

grunt.registerTask('deploy', ['lambda_package', 'lambda_deploy:default']);
grunt.registerTask('deploy_prod', ['lambda_package', 'lambda_deploy:prod']);
```

## Misc info

### Streamlining deploy

You can combine the lambda_package and lambda_deploy into a single deploy task by adding the following to your
 Gruntfile.js:

```js
grunt.registerTask('deploy', ['lambda_package', 'lambda_deploy']);
```

You can then run `grunt deploy` to perform both these functions in one step.

### AWS credentials

The AWS SDK is configured to look for credentials in the following order:

1. an IAM Role (if running on EC2)
2. an AWS CLI profile (from `~/.aws/credentials`)
3. environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`)
4. a JSON file on disk
5. Hardcoded credentials passed into grunt-aws

The preferred method of authenticating during local development is by providing credentials in `~/.aws/credentials`,
it should look something like this:

```
[default]
aws_access_key_id = <YOUR_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_SECRET_ACCESS_KEY>
```

For more information [read this documentation](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html).

### AWS permissions

To run the deploy command the AWS credentials require permissions to access lambda including `lambda:GetFunction`,
`lambda:UploadFunction`, `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration` and
`iam:PassRole` for the role which is assigned to the function.

It is recommended that the following policy be applied to the user:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1442787227063",
      "Action": [
        "lambda:GetFunction",
        "lambda:UploadFunction",
        "lambda:UpdateFunctionCode",
        "lambda:UpdateFunctionConfiguration",
        "lambda:GetAlias",
        "lambda:UpdateAlias",
        "lambda:CreateAlias",
        "lambda:PublishVersion"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:lambda:*"
    },
    {
      "Sid": "Stmt1442787265773",
      "Action": [
        "iam:PassRole"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:iam::<my_account_id>:role/<my_role_name>"
    }
  ]
}
```

## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).

## Release History
### 0.1.0
Initial release

### 0.2.0
Adding some unit tests, refactoring deploy task into single task and converting tasks to multitasks

### 0.3.0
Adding more warnings for various failure cases

### 0.4.0

* Added support for succeed and fail functions - [pull request by jonyo](https://github.com/Tim-B/grunt-aws-lambda/pull/11)
* Added NPM to package.json - [pull request by jonyo](https://github.com/Tim-B/grunt-aws-lambda/pull/13), should address [issue 2](https://github.com/Tim-B/grunt-aws-lambda/issues/2#issuecomment-104805707)
* Added timeout and memory options - [timeout pull request by aidancasey](https://github.com/Tim-B/grunt-aws-lambda/pull/3)
* Bumped aws-sdk version
* Bumped adm-zip version, will hopefully address [issue 4](https://github.com/Tim-B/grunt-aws-lambda/issues/4)

### 0.5.0
* Fixed issue where dotfiles weren't packaged - [see issue 17](https://github.com/Tim-B/grunt-aws-lambda/issues/17)
* Fixed issue where task could be done before zip writing is finished - [pull request by qen](https://github.com/Tim-B/grunt-aws-lambda/pull/16)
* Monkey patched node-archiver to force permissions to be 777 for all files in package - [see issue 6](https://github.com/Tim-B/grunt-aws-lambda/issues/6)

### 0.6.0
* Fixing a minor issue caused by some code that shouldn't have been commented out.

### 0.7.0
* Removing some unneeded files from the NPM package.

### 0.8.0
* Adding `include_files` option to package - [pull request by dhleong](https://github.com/Tim-B/grunt-aws-lambda/pull/19)

### 0.9.0
* Parsing region automatically from ARN - [pull request by jvwing](https://github.com/Tim-B/grunt-aws-lambda/pull/25)

### 0.10.0
* Making NPM a regular dependency to resolve [#20](https://github.com/Tim-B/grunt-aws-lambda/issues/20) - [pull request by timdp](https://github.com/Tim-B/grunt-aws-lambda/pull/27)

### 0.11.0
* Including AWS API error message in deployment failure - [pull request by CaseyBurns](https://github.com/Tim-B/grunt-aws-lambda/pull/40)
* Providing a method to pass AWS credentials in either the Gruntfile or credentials file - [pull request by robbiet480](https://github.com/Tim-B/grunt-aws-lambda/pull/34)
* Adding support for AWS temporary credentials - [pull request by olih](https://github.com/Tim-B/grunt-aws-lambda/pull/46)

### 0.12.0

* Added package_folder option to lambda_invoke task - [pull request by dcaravana](https://github.com/Tim-B/grunt-aws-lambda/pull/62)
* Adding optional files to contain JSON objects for clientContext and identity to be passed into the lambda_invoke command - [pull request by Skorch](https://github.com/Tim-B/grunt-aws-lambda/pull/51)
* Add handler option to lambda_deploy task - [pull request by Rawbz](https://github.com/Tim-B/grunt-aws-lambda/pull/52)
* Fix lambda_deploy config example - [pull request by pracucci](https://github.com/Tim-B/grunt-aws-lambda/pull/56)
* Context object methods cleanup - [pull request by ubergoob](https://github.com/Tim-B/grunt-aws-lambda/pull/58), also fixes [issue 54](https://github.com/Tim-B/grunt-aws-lambda/issues/54)
* When deploy_arn is not defined in the Gruntfile the value is undefined - [pull request by varunvairavan](https://github.com/Tim-B/grunt-aws-lambda/pull/60)
* Extensive refactoring to improve testability and a new unit test suite
* Bumped AWS SDK version to 2.2.32
* Added support for versioning and aliases
* Added support for excluding the package version from the package artifact name - based on [pull request by leecrossley](https://github.com/Tim-B/grunt-aws-lambda/pull/59)

### 0.13.0

* Added support for Node 4.3 runtime callback function - [pull request by bobhigs](https://github.com/Tim-B/grunt-aws-lambda/pull/76)
* Added VPC support - [pull request by beeva-arturomartinez](https://github.com/Tim-B/grunt-aws-lambda/pull/71)
* Added local proxy support - [pull request by alekstr](https://github.com/Tim-B/grunt-aws-lambda/pull/66)

---
_Source: https://npm.io/package/grunt-aws-lambda · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
