AWS LambdaのLayerを利用する3つの種類

AWS LambdaのLayerの作り方、使い方をよく忘れるので、備忘録として残しておきます。
以下の3つのことができるLayerを作ります。3つを選択的またはすべて含めたLayerにもできますので、必要なものをLayerに選択して含めてください。
対象言語はNode.jsの場合です。

①	自作のクラスを含める
②	Npmモジュールを含める
③	実行ファイルを含める

# 準備

まず適当なフォルダを作成します。例えば、layer_testというフォルダを作ります。以降、ここをルートフォルダとみなします。

```
> mkdir layer_test
> cd layer_test
```

作業環境に、Node.jsがセットアップされている前提です。
バージョンは、Lambdaで指定予定のバージョンに合わせます。今回は、v14系にしました。

# ①自作のクラスを含める

自作のクラスを含めます。
先ほど作成したルートフォルダに作成します。

```
> vi hello.js
```

中身はこんな感じです。

```js:hello.js
class Hello{
    constructor(message){
    	this.message = message;
    }

    say(){
        return this.message;
    }
}
module.exports = Hello;
```

AWS Lambdaへのアップロードは後でまとめて説明します。

# ②Npmモジュールを含める

次は、npmモジュールを含めてみます。
もちろん、Layerとしなくてもよいですが、大きなnpmモジュールの場合は、AWS管理コンソール上でソースコード編集できなくなる場合があるので、大きなファイルはLayerに追いやるのも一つの手です。
さきほどのルートフォルダで、nodejsフォルダを作成します。

```
> mkdir nodejs
> cd nodejs
> npm init -y
```

そして、含めたいnpmモジュールをインストールします。今回は、例としてuuidを含めます。

```
> npm install uuid
```

そうすると、nodejsフォルダに、node_modules フォルダが出来上がっているかと思います。
npmモジュールによっては、ネイティブコンパイルが行われる場合があります。その場合は、AWS LambdaはLinux環境なので、Windowsではなく、たとえばUbuntuなどのLinux環境で実施してください。

# ③実行ファイルを含める

child_processのexecSyncやexecなどで、ネイティブの実行ファイルを実行したい場合があります。
まずは、さきほどのルートフォルダで、binフォルダを作成します。

```
> mkdir bin
> cd bin
```

今回は、例として、「ffmpeg」を含めてみます。

以下のサイトから、ffmpeg-release-amd64-static.tar.xz をダウンロードしてきましょう。このとき、ダウンロードするのは、Linuxの実行ファイルです。Windows用ではないことに注意してください。

https://johnvansickle.com/ffmpeg/

tar.xzで圧縮されていますので、以下のように展開します。

```
> xz -dc ffmpeg-release-amd64-static.tar.xz | tar xfv –
```

そうすると、展開されたフォルダの中に、ffmpegとffprobeの2つの実行ファイルがあります。
これをルートフォルダのbinフォルダにコピーします。

```
> cp XXXX/{ffmpeg,ffprobe} .
```

# Layerにアップロードする

アップロードするには、まずはアップロードしたいファイル群をZIP化する必要があります。

結局こんなフォルダになっているかと思います。

```
***.js
bin\***
nodejs\node_modules\***
```

さきほどのルートフォルダで以下を実行します。

```
> zip -r index.zip .
```

これで、ZIPファイル「index.zip」が出来上がります。
それでは、AWS管理コンソールからZIPファイルをLayerとしてアップロードします。
 
https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/layers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/49271321-a141-da0a-5731-c34e510c3ffb.png)

「レイヤーの作成」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/cb2fca94-0f49-640f-70a2-fb9276d52fd5.png)

名前は適当に、「layer_test」にしました。
ZIPファイルのアップロードは、直接このページからアップロードするか、S3にいったんアップロードしてからLayerにアップロードするやり方があります。ZIPファイルが10メガバイトを超える場合は、S3経由でアップロードする必要があります。

互換性のあるアーキテクチャ-オプションは、x86_64を選択します。互換性のあるランタイム-オプションは、今回は「Node.js 14.x」を選択しました。

# Lambda関数から利用する

それでは、さっそくLambda関数から利用してみます。
ランタイムには、さきほどのLayerのランタイムに指定したNode.js 14.xを選択します。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/5fbd752c-acfd-cc9c-b361-d7ceffc5f89c.png)

Lambda関数を作成したら、下の方のレイヤーにある「レイヤーの追加」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f6211578-1f64-41e0-44e3-c359149b2cdc.png)

カスタムレイヤを選択し、先ほど作成した「layer_test」を選択します。
バージョンは、Layerの更新のたびに1インクリメントされてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/50c29bc0-9612-647d-8e0e-000d868ce9fd.png)

最後に、「追加」ボタンを押下します。

利用するときのソースコードは以下になります。
1点補足ですが、自作クラスは、フォルダ /opt 配下に展開されるようです。

```js:index.js
const Hello = require('/opt/hello');
const { v4: uuidv4 } = require('uuid');
const execSync = require('child_process').execSync;

exports.handler = async (event) => {
    var hello = new Hello("Hello World");
    console.log(hello.say());
    
    var uuid = uuidv4();
    console.log(uuid);

    var message = execSync('ffmpeg -version');
    console.log(message.toString());

    
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

以上