LoginSignup
16
17

More than 5 years have passed since last update.

Lambda Layers をnode.js(SAM)で試してみる

Last updated at Posted at 2018-12-02

re:Invent2018で「Lambda Layers」なるものが発表されました。
これで、私が抱えていた「複数のLambda Functionで共有するものをどうやって同期・更新していくか問題」と「ちょっとしたFunctionで試したいときに外部ライブラリが使えない問題」を解決できるはずです。

参考文献

Lambda Layersとは

Lambda Layers, 複数の関数で共用されるコードやデータをセンタライズし管理するものです

https://aws.amazon.com/jp/blogs/news/new-for-aws-lambda-use-any-programming-language-and-share-common-components/

まずはLayer

Layerに moment.js を入れて、Lambda Functionから参照するというのをやってみます。

LayerはFunctionと同じようにzipファイルをアップロードするという形式のようです。
そのzipファイルはドキュメントによると以下のような構成ということです。

Node.js – nodejs/node_modules, nodejs/node8/node_modules (NODE_PATH)
Example AWS X-Ray SDK for Node.js

xray-sdk.zip
└ nodejs/node_modules/aws-xray-sdk

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html

これに合わせて、ローカルで準備します。

$ mkdir -p layer/nodejs
$ cd layer/nodejs
$ npm init -y
$ npm install moment
$ cd ../..
$ zip -r ../layer.zip ./
  adding: nodejs/ (stored 0%)
  adding: nodejs/node_modules/ (stored 0%)
  adding: nodejs/node_modules/moment/ (stored 0%)
  adding: nodejs/node_modules/moment/CHANGELOG.md (deflated 71%)
  adding: nodejs/node_modules/moment/ender.js (deflated 5%)
(以下略)

出来上がったzipファイルを適当なS3Bucketにアップロードします。

$ cd ..
$ aws s3 cp ./layer.zip s3://<BUCKET>/

これをデプロイ(Layerもデプロイっていうのかな?)するためのSAMテンプレートを作成します。

layer-sam.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  SharedLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: SharedLayer
      Description: include moment
      ContentUri: 's3://<BUCKET>/layer.zip'
      CompatibleRuntimes:
        - nodejs6.10
        - nodejs8.10
      LicenseInfo: 'Available under the MIT-0 license.'
      RetentionPolicy: Retain
Outputs:
  LayerVersionArn:
    Value: !Ref SharedLayer

aws cloudformation deployコマンドでデプロイします。

aws cloudformation deploy \
  --stack-name shared-layer \
  --template-file layer-sam.yaml

作成されたLayerのArnは後で使うので確認しておきます。

$ aws cloudformation describe-stacks --stack-name shared-layer --query "Stacks[].Outputs"
[
    [
        {
            "OutputKey": "LayerVersionArn",
            "OutputValue": "arn:aws:lambda:us-west-2:xxxxxxxxxxxx:layer:SharedLayer:1"
        }
    ]
]

Layerを参照するFunction

Layerにあるmomentを利用するFunctionを作成します。

functions/Func1/index.js
const moment = require('moment');
exports.handler = async (event) => {
    return {
        moment: moment().format()
    };
}; 

Func1をdeployするためのtemplateファイルをfunctionsディレクトリに作成します。

functions/app-sam.yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
  Func1:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: Func1
      Handler: index.handler
      MemorySize: 128
      Runtime: nodejs8.10
      Timeout: 300
      Layers:
        - "arn:aws:lambda:us-west-2:xxxxxxxxxxxx:layer:SharedLayer:1"

Layersプロパティに先程のCloudFormationで作成したLayerのArnを指定します。

$ aws cloudformation package \
  --template-file app-sam.yaml \
  --s3-bucket <BUCKET> \
  --output-template-file app-output_sam.yaml

app-output_sam.yamlが出来上がっているのでデプロイします。

aws --region us-west-2 cloudformation deploy \
  --stack-name layer-functions \
  --template-file app-output_sam.yaml \
  --capabilities CAPABILITY_IAM

ではFunctionを実行してみましょう。

$ aws lambda invoke --function-name Func1 output.txt
$ cat output.txt
{"moment":"2018-12-02T14:49:29+00:00"}

これで、Lambda Functionのアップロードファイルに含まれていないライブラリが呼べることが確認できました。

ちょっとしたLambda Functionで外部ライブラリ使えない問題

ちょっとしたお試しでLambda FunctionをManagementConsoleから作ったときに、
これまでは外部ライブラリを呼ぶことができませんでした。
Layersを使えばそれもできるはず!と試してみました。

image.png

Layersを選択すると「レイヤーの追加」ができるのでクリックする。

image.png

先ほど作成したLayerがあるので選択して接続する。

以下のコードを入力して実行してみる。

const moment = require('moment');
exports.handler = async (event) => {
    console.log(moment().format());
    return {};
};

きちんとログに出ていれば成功!

image.png

課題

CodeBuild(それ以外のCIでもいいけど)でFunctionをテストするときに、Layerに依存しているFunctionを確実に実行時と同じLayerを適用してテストするにはどうしたもんか。。。

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17