Serverless Frameworkでnpmパッケージ(for Alexa)をLambda Layerにデプロイする

Lambda Layer便利そうですよね。Lambdaのデプロイパッケージサイズ節約や社内ライブラリの一元管理などなど、いろいろ捗りそうな予感がMAXです。 そしてServerless Frameworkでの使い方が公式 […]

広告ここから
広告ここまで

目次

    Lambda Layer便利そうですよね。Lambdaのデプロイパッケージサイズ節約や社内ライブラリの一元管理などなど、いろいろ捗りそうな予感がMAXです。

    そしてServerless Frameworkでの使い方が公式で紹介されていましたので、早速試してみます。

    今回やること

    Alexaスキル開発でよく使うライブラリ(ASK SDK v2 & ask-utils)をLayer化して、毎回npm iしなくてすむようにします。

    準備

    Serverless Frameworkのバージョンが1.34.0以上である必要があります。すでに利用している方はnpm i -g serverless@latestなどで更新しておきましょう。

    ディレクトリ構成

    pipやnpm / yarnで追加したライブラリは配置する場所が指定されています。

    Including Library Dependencies in a Layer

    今回はnpmのパッケージを入れますので、以下のようなディレクトリ構成にしましょう。

    $ tree -L 3
    .
    ├── files
    │   └── nodejs
    │       ├── node_modules
    │       ├── package.json
    │       └── yarn.lock
    └── serverless.yml

    filesというディレクトリ名については任意で構いません。ただしnodejsディレクトリ配下にnode_modulesディレクトリが来るようにしてください。

    コマンドは以下のように実行すれば良いでしょう。

    $ touch serverless.yml
    $ mkdir -p files/nodejs
    $ cd files/nodejs
    $ npm init -y
    $ yarn add ask-sdk ask-utils

    Serverless.ymlの作成

    Serverless Frameworkの構成はYAMLで定義します。Layerの場合は以下のように記述しましょう。

    service: ask-sdk-layers
    frameworkVersion: ">=1.34.0"
    provider:
      name: aws
      runtime: nodejs8.10
    
    layers:
      helloLayer:
        description: ASK SDK Packages
        path: files
        compatibleRuntimes:
          - nodejs8.10

    frameworkVersionは必須ではありませんが、古いバージョンでsls deployを実行しても何もおきませんので、エラーを出してやる方が親切かなと思います。

    path./のようにカレントディレクトリを指定すればfilesディレクトリを作らずにすむかなと思ったのですが、意図した通りにデプロイパッケージが作られませんでした。

    デプロイ

    ここまで準備できればOKです。あとはsls deployでデプロイしてやりましょう。

    Service Information
    service: ask-sdk-layer
    stage: dev
    region: us-east-1
    stack: ask-sdk-layers-dev
    api keys:
      None
    endpoints:
      None
    functions:
      None
    layers:
      helloLayer: arn:aws:lambda:us-east-1:99999999:layer:helloLayer:1

    layersに表示されているARNをLambdaでLayerに指定してやることで、追加したパッケージ群を読み込むことができます。

    そしてLayersはLambda@edge同様バージョン管理となります。Layerを更新した際は必ずバージョンを変更してやるようにしましょう。

    Serverless Frameworkで作ったLayerを利用する

    最後に作ったLayerを利用する方法を紹介します。

    通常Lambdaをデプロイするときは、functionsブロックに設定を記述していきます。Layerについても同様で、以下のようにARNを指定してやるだけでOKです。

    service: first-alexa
    provider:
      name: aws
      runtime: nodejs8.10
    
    functions:
      hello:
        handler: index.handler
        layers:
          - arn:aws:lambda:us-east-1:99999999:layer:helloLayer:4

    同一のserverless.ymlで管理する場合は、CloudFormationのRefが使えます。

    service: practice-of-layer
    frameworkVersion: ">=1.34.0"
    provider:
      name: aws
      runtime: nodejs8.10
    
    layers:
      hello:
        description: My first layer
        path: files
        compatibleRuntimes:
          - nodejs8.10
    
    functions:
      hello:
        handler: index.handler
        layers:
          - {Ref: HelloLambdaLayer}

    「1文字目大文字」と「LambdaLayerが後ろにつく」という命名規則にだけ注意してください。

    テスト

    最後に実際に動くか確認しましょう。

    $ sls invoke local -f hello -d '{
      "version": "1.0",
      "session": {
        "new": true,
        "sessionId": "amzn1.echo-api.session.123456789012",
        "application": {
          "applicationId": "amzn1.ask.skill.987654321"
        },
        "user": {
          "userId": "amzn1.ask.account.testUser"
        },
        "attributes": {}
      },
      "context": {
        "AudioPlayer": {
          "playerActivity": "IDLE"
        },
        "System": {
          "application": {
            "applicationId": "amzn1.ask.skill.987654321"
          },
          "user": {
            "userId": "amzn1.ask.account.testUser"
          },
          "device": {
            "supportedInterfaces": {
              "AudioPlayer": {}
            }
          }
        }
      },
      "request": {
        "type": "LaunchRequest",
        "requestId": "amzn1.echo-api.request.1234",
        "timestamp": "2016-10-27T18:21:44Z",
        "locale": "en-US"
      }
    }'

    これでちゃんとレスポンスのJSONが返って来くればOKです。

    Layerを使うメリット

    Lambdaのコンソールからコードがみれます。地味にこれ結構嬉しくて、ちょっとconsole.logでデバッグしたいときにいちいちsls deploy functionしなくても大丈夫です。

    また、スキルを複数構築していると「いつも使うパッケージ群」が出て来ます。

    これを毎回npm iとかyarn addしたりするのが結構面倒なので、「オレオレLayer」を仕込んでおくと便利そうです。

    「npmに公開したいわけではないけど、プロジェクトまたぎで使うから共通化したい」というソースコードがあれば、Lambda Layerがかなり便利かなと思います。

    ということで、この記事はAlexa skill Advent Calendar 2018Alexa Skills Kit SDK Advent Calendar 2018の10日目を埋めるために書きました。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark