皆様こんにちは。
キャスレーコンサルティング・ID(インテグレーション&デザイン)部の田中(雅)です。

今回は、11月末に行われた「AWS re:Invent 2018」の中で発表があった
AWS LambdaのLayerについて、どういったことができるかを試していきたいと思います。

AWS LambdaのLayerとは

複数のLambdaから、Layer内のモジュールを呼び出すことで、
Lambda内の処理を、簡潔にすることができます。
また、node_modules 等の大量のファイルを、都度圧縮してアップロードする手間も減ります。

Layerが使える前のLambda

今まで、funcA、funcBのような形で同じモジュールを利用する場合、
両方のLambdaに、同じモジュールのファイルを含めた形で、登録する必要がありました。

Layerを使用した場合のLambda

Layerを使用することで、funcA,funcBの中ではモジュールファイルを登録する必要はなく、
Layerを登録するだけで、Layer内のモジュールを利用することができます。

 

それでは、実際にこの便利なLayerの使い方と作成を実施して
Lambdaの本体がどうなるかを、試していきたいと思います。

開発環境

Node.js macOS Sierra 10.14

Layerの作成

今回は、log4js というlogger を呼び出すLayerを作成します。
※ 今回は、node.js にて動かしていきます。

それでは、早速Layerを作っていきましょう!

1. 必要モジュールのインストール

Layer のPATHは
nodejs/node_modules, nodejs/node8/node_modules となっている必要がありますので
このようにするためにディレクトリを作成し、
今回使用するlog4jsとlog4js_extendを、インストールします。

※AWSのドキュメント

mkdir -p skill-blog-layer/nodejs
cd skill-blog-layer/nodejs
npm init -y
npm install --save log4js
npm install --save log4js-extend

2. 共通化処理の実装

Lambda から呼ぶモジュールである、「layer.js」を作成していきます。

mkdir node_modules/layer
cd node_modules/layer/
npm init
# entry point: (index.js) のときだけ「layer.js」と打ってください。
 あとはすべてエンターで行きます。
vi layer.js

↓を貼り付ける

'use strict';
const log4js = require('log4js');
const log4jsExtend = require('log4js-extend');
log4js.configure(__dirname + '/config/log.json');
// 関数名、プログラムの行数などをつける
log4jsExtend(log4js, {
    path: __dirname,
    format: "at @name (@file:@line:@column)"
});
const logger = log4js.getLogger('console');

module.exports.logger = logger;

3. loggerの設定ファイル作成

loggerの書式を設定するファイルを、作成します。

mkdir config
vi config/log.json

↓を貼り付ける

{
    "appenders": {
        "console": {
            "type": "console",
            "layout": {
                "type": "pattern",
                "pattern": "%p:[%z] %m"
            }
        }
    },
    "categories": {
        "default": {
            "appenders":
            ["console"],
            "level": "trace"
        }
    }
}

ログの出力設定を記述した、ファイルになります。

詳しくは、log4jsのgithubをご覧ください。

こちらで、Layerの実装は完成です!

Layer自体のディレクトリ構成は、こちらとなります。

└── nodejs
├── node_modules
│ ├── layer
│ │ ├── config
│ │ │ └── log.json
│ │ ├── layer.js
│ │ └── package.json
│ ├── log4js
│ │ │
〜〜〜〜〜〜
│ │ │
│ ├── log4js-extend
〜〜〜〜〜〜
│ ├── minimist
〜〜〜〜〜〜
├── package-lock.json
└── package.json

最後に、zip で固めて、layer-skill-blog.zipとして保存します。

cd ../../../
zip -r layer-skill-blog.zip ./nodejs/

4. Layerの登録

では、早速Layerを登録してみましょう!

AWSにログインし、
サービス ⇨ AWS Lambda ⇨ Layer
を選択します。

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

「名前」を入力し、先程作った「layer-skill-blog.zip」をアップロードします。
ランタイムの選択は、「Node.js 8.10」を選択します。
胸に手を当てて、「作成」ボタンを押します!
こちらで、Layerの作成・登録は完了です。

Layerを使用する、Lambdaの作成

1. Lambdaの登録

AWSのサイドバーに関数とありますので、そちらを押します。

「関数の作成」ボタンを押します。

名前・ロールは適宜選択し、ランタイムは「Node.js 8.10」を選択します。

「Layers」を押し、「レイヤーの追加」を押します。

「関数にレイヤーを追加」の画面では、
レイヤーに先程登録した「skill-blog」 バージョンは「1」を選択し、「追加」ボタンを押します。
これで、Layerの登録は完了です。

Lambdaのソースですが、

  • ログレベルの設定
  • Layerの呼び出し
  • ログレベルに応じたloggerの呼び出し

になります。

const LOG_LEVEL = 'error';
const Layer = require('layer');
const logger = Layer.logger;
logger.level = LOG_LEVEL;


exports.handler = () => {
    logger.trace('trace log');
    logger.debug('debug log');
    logger.info('info log');
    logger.warn('warn log');
    logger.error('error log');
    logger.fatal('fatal log');
}

index.js のみで用意せずに、log4jsモジュールが呼べるので
AWSのコンソールでも、簡単に作ることができます。

2. Lambdaの実行

「保存」ボタンを押し、テストイベント登録後に「テスト」ボタンを押すと実行結果が表示されます。

index.js の中で、ログレベルをerror以上にしているので
errorとfatalのみ出力されていることがわかります。

終わりに

いかがでしたでしょうか。
Layerを使うと、Lambdaとして登録するファイルが減り、
デプロイやテストする際の手間を減らすことができます。

また、それぞれのLambdaで呼ばれる、共通処理のテストも減らせるようになりますね。
今回は触れませんでしたが、Layerについてもバージョンを複数持つこともできるため、
異なるバージョンでの並行稼動にも容易に対応することができ、切り戻しなども簡単です。

AWSは進化が非常に早く、日々機能改善されています。
こういった技術を取り入れ、日々の業務に生かしていきたいと思います!

最後までお読みいただき、ありがとうございました。

田中(雅)
CSVIT事業部 ID(インテグレーション&デザイン)部 田中(雅)
最近はAWS,node.jsを勉強中です!