Taste of Tech Topics

Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Serverless Frameworkで AWS Lambda Layers を試してみる

こんにちは、最近のクラウドシステム開発は、ほぼサーバーレス・アーキテクチャで対応している takanorig です。
この記事は Serverless Advent Calendar 2018 の9日目の記事です。

昨日は、システムテスト自動化カンファレンス2018で、「マイクロサービスのテスト自動化 with Karate」という内容で発表をしてました。
上記はテスト自動化に関する内容ですが、こちらも、サーバーレス・アーキテクチャの関連があって利用を始めたもの。
当初、このKarateを使っての内容を書こうかと思っていたのですが、今回のタイトルの内容の方が自分的に優先度が高くなったので、内容を切り替えての投稿です。

f:id:acro-engineer:20181210075313j:plain

はじめに

先日のre:Invent2018で AWS Lambda Layers が発表されましたが、「これはPJで早速導入したい」と思った内容でした。
社内のプロジェクトでは、主にServerless Frameworkを使ってServerlessなサービスの開発を行っているのですが、Lambda Layers を使えるのかな?と思って確認したところ、Serverless Frameworkでも既に対応されていました!(対応が早い)。

ということで、本エントリーでは、Serverless Frameworkで、AWS Lambda Layers を試してみます。

※今回の内容は、AWS Lambda/Serverless Framework 自体の基本的な知識は有していることを前提にしています。

AWS Lambda Layers とは?

既にご存知の方も多いかもしれませんが、簡単に、どういうものか説明しておきます。

従来のLambdaでは、共通モジュール(共通で利用するファンクションやライブラリなど)がある場合に、それを利用する各ファンクションと合わせて、それぞれごとにパッケージングしてデプロイすることが必要でした。その分、パッケージのサイズが肥大化したり、その分デプロイに時間がかかってしまう、という課題がありました。

Lambdaでも、それなりの規模の開発になってくると、当然、共通モジュールなども増えてきますよね。

これに対して、Lambda Layers を使うことで、上記のような課題を解決できる状況になりました。Lambda Layers は、共通モジュールをひとつのzipファイルにまとめてアップロードし、各ファンクションから呼び出すことができるようになります。

Serverless Framework での Lambda Layers の利用

公式サイトの情報として、以下が参考になります。

環境

今回は、以下のような環境で確認をしています。
Layersの機能を利用するためには、Serverless Frameworkは、1.34.0以上であることが必要です。

環境 バージョン
Mac macOS Mojave 10.14.1
node 10.14.1
npm 6.4.1
Serverless Framework 1.34.1
言語 Python 3.6.0

前準備

今回、Pandasを利用した処理を試してみます。
そのためには、予め Amazon Linux 環境でビルドしたファイルを用意する必要があります。

まず、Pandasをビルドするに、ディレクトリ構成を以下のようにしています。

sls-layers-example
  └── layers
      └── pandas
          ├── package.sh
          └── requirements.txt

それぞれのファイルの中身は、以下のようになります。

  • package.sh
#!/bin/sh

export OUTPUT_DIR="python"

rm -rf ${OUTPUT_DIR} && mkdir -p ${OUTPUT_DIR}

docker run --rm -v $(pwd):/var/task -w /var/task lambci/lambda:build-python3.6 \
    pip install -r requirements.txt -t ${OUTPUT_DIR} 

ここでは、簡単に Amazon Linux の環境でビルドできるように、 lambci/docker-lambda を利用しています。
これを使うと、Dockerを利用してビルドができますね。

  • requirements.txt
pandas==0.23.4

上記の準備ができたら、Pandasのビルドを行います。

$ cd /{path}/sls-layers-example
$ cd layers/pandas
$ ./package.sh
Collecting pandas==0.23.4 (from -r requirements.txt (line 1))
・・・
Installing collected packages: six, python-dateutil, pytz, numpy, pandas
Successfully installed numpy-1.15.4 pandas-0.23.4 python-dateutil-2.7.5 pytz-2018.7 six-1.11.0

上記のように、ビルドが成功すればOKです。

serverless.yml / Lambda関数 の作成

先ほどのディレクトリ構成に対して、以下のように serverless.ymlanalysis_lambda.py を追加します。

sls-layers-example
  ├── analysis_lambda.py
  ├── layers
  │   └── pandas
  │       ├── package.sh
  │       └── requirements.txt
  └── serverless.yml
  • serverless.yml
service: sls-layers-example

frameworkVersion: ">=1.34.0 <2.0.0"

provider:
  name: aws
  runtime: python3.6
  stage: dev
  region: us-west-2

package:
  individually: true

# AWS Lambda Layers
layers:
  pandas:
    path: layers/pandas
    name: ${self:service}-pandas
    compatibleRuntimes:
      - python3.6
    allowedAccounts:
      - '*'

# AWS Lambda Functions
functions:
  analyze:
    handler: analysis_lambda.analyze
    layers:
      - {Ref: PandasLambdaLayer}
#     - arn:aws:lambda:${self:provider.region}:xxxxxxxxxxx:layer:{service名}-{layer名}:{バージョン}

既に登録されているLayerを使う場合は、ARNの形式で指定する必要がありますが、同じserverless.ymlで参照する場合は、「PandasLambdaLayer」(Layerに応じてCloudFormationで名前が設定される)のような名称で参照ができます。

  • analysis_lambda.py
# -*- coding: utf-8 -*-
import pandas as pd

def analyze(event, context):
    names = ['Bob','Jessica','Mary','John','Mel']
    births = [968, 155, 77, 578, 973]

    BabyDataSet = list(zip(names,births))

    df = pd.DataFrame(data = BabyDataSet, columns=['Names', 'Births'])
    print(df)

ここでは簡単に、配列から、DataFrameを利用して、データセットを作成しています。

デプロイ

ここまでくれば、あとはデプロイするだけです。

$ cd /{path}/sls-layers-example
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (609 B)...
Serverless: Uploading service .zip file to S3 (32.64 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
・・・・

Pandasのライブラリの部分は、32.64MBありますね。
それなりのサイズになっています。

デプロイ結果確認

AWSコンソールにログインして、デプロイ結果を見てみましょう。
以下のように、キチンと「Layer」に登録されており、Lambda関数からも参照できているようです。

f:id:acro-engineer:20181210071340p:plain
Layers

ビルドしたPandasが、Layerとして登録されています。

f:id:acro-engineer:20181210071407p:plain
Function

Layerに登録されたPandasが、「参照されるレイヤー」の部分で確認できます。

テスト

デプロイされたLambdaをテストしてみます。

f:id:acro-engineer:20181210071527p:plain
Test

f:id:acro-engineer:20181210071550p:plain
Result

AWSコンソールの機能で、テストを実行してみたところ、きちんと実行ができたようです!

注意点

Layersを使う場合の制限は、予め把握した上で利用する必要があります。
特に注意すべき点は、以下の内容でしょう。

  • Layerは、5つまで。
  • デプロイ可能なサイズは、圧縮したサイズ:50 MB/解凍した際にLayerも含めたサイズ:250 MB

詳細は、以下から確認ができます。

まとめ

ServerlesFrameworkから、AWS Lambda Layers を使ってみました。

これで、各関数で共通的に必要となる共通モジュールの管理が、より整理でき、効率的な開発ができそうです。
また、Layersでは、バージョンごとに保存されるようにもなっているので、複数の関数で、同時に変更ができないような場合でも対応できそうです。



Acroquest Technologyでは、キャリア採用を行っています。