Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dwyl/aws-lambda-deploy

☁️ πŸš€ Effortlessly deploy Amazon Web Services Lambda function(s) with a single command. Less to configure. Latest AWS SDK and Node.js v20!
https://github.com/dwyl/aws-lambda-deploy

Last synced: about 1 month ago
JSON representation

☁️ πŸš€ Effortlessly deploy Amazon Web Services Lambda function(s) with a single command. Less to configure. Latest AWS SDK and Node.js v20!

Awesome Lists containing this project

README

        

![dpl-logo](https://cloud.githubusercontent.com/assets/194400/13200090/e0a7831c-d831-11e5-809e-4a802b267045.png)

Deploy your AWS Lambda function(s) in seconds with a single command.

[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/dwyl/aws-lambda-deploy/ci.yml?label=build&style=flat-square&branch=main)](https://github.com/dwyl/aws-lambda-deploy/actions)
[![codecov.io](https://img.shields.io/codecov/c/github/dwyl/aws-lambda-deploy/master.svg?style=flat-square)](http://codecov.io/github/dwyl/aws-lambda-deploy?branch=master)
[![npm package version](https://img.shields.io/npm/v/dpl.svg?color=brightgreen&style=flat-square)](https://www.npmjs.com/package/dpl)
[![HitCount](http://hits.dwyl.com/dwyl/aws-lambda-deploy.svg)](http://hits.dwyl.com/dwyl/aws-lambda-deploy)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/aws-lambda-deploy/issues)



## Why? 🀷

Deploying Lambda functions *manually* involves quite a few steps.
Manually clicking buttons to upload zip files is fine the first few times
but gets old pretty quickly.
There is an *easier* way!

## What? πŸ’­

Simplify the process of deploying a AWS Lambda Function
*without having to adopt a build tool/system*.

## How? βœ…

There are ***5 Steps*** to setup deployment for your Lambda Function:

### 1. install the `dpl` package from NPM πŸ“¦

```sh
npm install dpl --save-dev
```

### 2. Ensure that the *required* AWS Environment Variables are set: πŸ”

In order to use `dpl` to deploy your Lambda function,
you need to have a few environment variables defined.
e.g: `AWS_REGION` and `AWS_IAM_ROLE`.

We have created a
[`.env_sample`](https://github.com/dwyl/aws-lambda-deploy/blob/master/.env_sample)
file that shows you _exactly_ which environment variables you need.

Simply copy it into your project. e.g:

```sh
cp node_modules/dpl/.env_sample .env && echo ".env\n" >> .gitignore
```

And then update the values with the _real_ ones for your project.

> **Note**: You need to have your AWS Credentials set
to use the `aws-sdk`

if you have not yet done this,
see below for instructions.

### 3. Add the *list* of `files_to_deploy` entry to your `package.json` πŸ“

In your `package.json` file, add the list of files & directories
you want to be included in this zip that gets uploaded to AWS.

Example:
```js
"files_to_deploy": [ "package.json", "index.js", "lib/" ]
```

> Sample: [package.json#L14-L17](https://github.com/dwyl/aws-lambda-deploy/blob/81766f9c20157039e14703e36dbbbaef4cfb4ac3/package.json#L14-L17)

### 4. Add a deployment script to the `scripts` section in `package.json` πŸ“œ

Example:
```js
"scripts": {
"deploy": "dpl"
}
```

### 5. Use the script to *Deploy*! πŸš€

```sh
npm run deploy
```


### *Congratulations* your Lambda Function is Deployed! πŸŽ‰


### *Troubleshooting* πŸ™…β€

> If you see an *error* message in your console,
> read the message and resolve it by correcting your setup.
> you have either not set your AWS Credentials or not defined
> the required environment variables.
> If you get stuck or have questions,
[*ping* us!](https://github.com/dwyl/aws-lambda-deploy/issues)

## *Implementation Detail* πŸ‘·β€

### *Required* Environment Variables πŸ”

Deploying your Lambda function requires a few Environment Variables
to be set.

#### AWS Credentials πŸ•Έ

As with all node.js code which uses the `aws-sdk`,
it expects to have your AWS credentials stored *locally*.
Your credentials are *expected* to be at: `~/.aws/credentials`
(*e.g: if your username is* ***alex***, *your AWS credentials will
be stored at* `/Users/alex/.aws/credentials`)
If you have not yet set your AWS credentials on your machine
do this *now*. Read about the [AWS credential format](http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-file-format).

#### `AWS_IAM_ROLE`

The script needs to know which `AWS_IAM_ROLE`
you want to use to deploy/run the function.

Example:
```sh
export AWS_IAM_ROLE=arn:aws:iam::123456789:role/LambdaExecRole
```

#### `AWS_REGION` (*where your lambda function will be deployed*)

Example:
```sh
export AWS_REGION=eu-west-1
```

#### *Optionally* you can define a `TMPDIR` Environment Variable

To make the deployment script's run faster,
and avoid forcing people to add entries into their `.gitignore` file,
we store the `/dist` directory and resulting `.zip` file
in your OS's Temporary storage.

e.g:
```sh
export TMPDIR=/path/to/where/you/want/dist/
```

### Two things to add to your `package.json`

For the deploy scrip to do its job,
we need to add two lines to our `package.json`

### List of `files_to_deploy`

In your `package.json` file, add the list of files & directories
you want to be included in your distribution.

Example:
```js
"files_to_deploy": [ "package.json", "index.js", "lib/", ".env" ]
```

This tells `dpl` to copy these files and directory (with all contents)
to the `/dist` which will be zipped and sent to AWS.

Check our
[package.json#L14-L17](https://github.com/dwyl/aws-lambda-deploy/blob/81766f9c20157039e14703e36dbbbaef4cfb4ac3/package.json#L14-L17)
file if in doubt.


## Explanation of the Steps πŸ‘©β€πŸ«

### `dpl` ("*Deploy Lambda*") performs the following 5 tasks

#### 1. *Create* the `/dist` (*distribution*) directory πŸ“

Instead of uploading *all* the files in a project to S3/Lambda we upload only
the *required* files. e.g: `/src` or `/lib` and `./index.js`.
While we are preparing this package, these required files are *copied* to
the (*temporary*) `/dist` directory which will be *zipped* in Step 5.

> Why a *temporary* directory?
see: http://stackoverflow.com/questions/17946360/what-are-the-benefits-of-using-the-official-temp-directory-for-the-os


#### 2. *Copy* required files into `/dist` directory β˜•οΈ

This typically includes the following:

+ `lib/` - the directory containing custom code your lambda function uses.
+ `package.json` - the "manifest" file for your project,
includes the Lambda function name, any configuration and dependencies.
+ `index.js` - the "*main*" `handler` of your Lambda function.


#### 3. *Install* (*only production*) `node_modules` in `/dist` directory πŸ“₯

We only need the "*production*" dependencies to be zipped and shipped.
so instead of copying all the *devDependencies* in `node_modules`,
we simply install a fresh set using the `--production` flag.


#### 4. *Zip* the contents of the `/dist` folder to `{function_name}.zip` πŸ“¦

Once the `/dist` directory has been created with the necessary files
and the dependencies have been installed in `/dist/node_modules`
we `zip` the "*distribution*" ready for uploading to AWS.

This can take a few seconds depending on how many dependencies your
Lambda function has.


#### 5. *Upload* πŸš€

Once the `zip` has been packaged we upload it to AWS using the `aws-sdk`.
Your Lambda function will be named according to the `"name"` in
the `package.json` file for your project.

> **Note**: We are using the ***latest stable version*** of **Node.js**
when deploying packages.
see: https://aws.amazon.com/blogs/compute/node-js-4-3-2-runtime-now-available-on-lambda/
If for any reason you *prefer*/*need* to use
the "*Old*" (*legacy*) version, please let us know:
https://github.com/dwyl/aws-lambda-deploy/issues/33


### Advantages of using `dpl` to *deploy* your Lambdas πŸ’‘

+ **Minial Dependencies** - Our solution to the deployment task uses only *one*
core dependency: the [`aws-sdk`](https://github.com/aws/aws-sdk-js).

+ **Small Code** - The *entire* `dpl` ("*Deploy Lambda*") module is fewer lines
than our original
[`gulpfile.js`](https://github.com/dwyl/aws-lambda-canary/blob/d18ccc099ec4ab1a7a612716563ec57364c03cc4/gulpfile.js)
and uses *only* node.js core modules
(*you know and love*) and your OS-native `zip` command.

+ A *beginner* can ***read and understand*** all the code used in `dpl`
in a few minutes; our code has *both* JavaDoc and *in-line comments* and we are
[*here*](https://github.com/dwyl/aws-lambda-deploy/issues)
to help if you have *any questions*!

+ **No assumptions** about your code style.
e.g if you need any custom processing
simply add a task in your `scripts` section of your `package.json`
and run that task before deploying.

+ **No _Global_ packages** required or implied, just *one `dev` Dependency*.

###Β Optional configuration

Want to specify the `MemorySize` or `Timeout` settings for your Lambda function?

+ `"lambda_memory"` - maximum memory allocation for your lambda function.
+ `"lambda_timeout"` - maximum execution time.

In your `package.json` add:

```js
"lambda_memory":"512",
"lambda_timeout": "30",
```

### *Environment Variables*?

Unlike other AWS Lambda deployment methods,
`dpl` lets you use environment
variables in your Lambda Functions!

Simply add `.env` to your list of `"files_to_deploy"` in your `package.json`

Example:
```js
"files_to_deploy": [ "package.json", "index.js", "lib/", ".env" ]
```
And an `.env` file will included in your `.zip` file that gets uploaded to AWS.
This means you can use an Environment Variable loader
e.g [`env2`](https://www.npmjs.com/package/env2)
in your Lambda function:

```js
require('env2')('.env');

exports.handler = (event, context) => {
if (event.hello === 'world') {
return context.fail(JSON.stringify({
statusCode: 500,
message: 'sorry'
}));
} else {
return context.succeed({
statusCode: 200,
message: process.env.HELLO // or how ever you use environment variables!
});
}
};

```

## Suggested Reading πŸ‘€

+ Using NPM as a build tool:
http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/
(*you don't need gulp/grunt/etc...*)