🚀

NumpyやPillowなどの依存を含むLambdaをServeless frameworkでデプロイする

2022/03/19に公開

はじめに

non-pure-Pythonの外部モジュールを含むLambda

NumpyやPillowなどの(C呼び出し等使った)non-pure-PythonなモジュールをLambda内で使う場合には,ひと手間必要で,大きく以下の2つの方法があります.

  • (A) 外部モジュールをAmazon Linuxでビルドしてデプロイパッケージに直接含めるもしくはそれをLambdaレイヤーとしてデプロイして参照する.
  • (B) コンテナイメージを使う.

外部モジュールをデプロイパッケージに含める場合,サイズが50MBという制限があります.(Lambdaレイヤーを使う場合には,250MB).一方のコンテナイメージでは,イメージサイズの上限が10GB以下となるため,サイズ制約が緩和されますが,ECRへのプッシュなど開発&デプロイは複雑になります.

外部モジュールをビルドする手間

状況次第ですが,サイズが250MBに収まる場合には,(A)を選択する場合が多いのかと思います.
(A)を行う場合には,Dockerなど用意したAmazon Linux環境内でpip installしてその生成物を取り出すという作業が必要ですが,Serverless frameworkを使ってLambdaをデプロイする場合には,この作業をpluginにより簡略化することができます.

この記事では,Serverless frameworkを使って,Numpy, Pillowなどnon-pure-Pythonのモジュールを含むLambda関数をデプロイする手順について書きます.

参考

事前準備

以下をインストール/セットアップしておく.

  • Serverless framework
  • Docker
  • AWSの認証情報

手順

1. サービスの作成

ServerlessでAWS Lambdaのサービスを作成する.

ここでは,sls-python-tutorialというサービス名にします.

sls create --template aws-python3 --path sls-python-tutorial

sls-python-tutorialディレクトリに以下のファイルなどが生成される.

  • serverless.yml: Serverlessの構成ファイル
  • handler.py: 処理の関数

2. ブラグインのインストール

NumpyやPillowのライブラリを使えるようにするため,serverless-python-requirementsというプラグインを使います.

# ディレクトリへ移動
cd sls-python-tutorial

# プラグインを追加
sls plugin install -n serverless-python-requirements

3. プラグインの設定を追加

serverless.ymlserverless-python-requirements用の設定を追加する.

custom:
  # serverless-python-requirementsの設定
  pythonRequirements:
    # 依存のコンパイルにdockerを使う
    dockerizePip: true
    
    # キャッシュの設定
    useDownloadCache: true
    useStaticCache: true

dockerizePipはPure-pythonではないライブラリをLinux以外のホスト(windowsやmac)からデプロイする場合は必須です.

requirements.txtを作成

Pythonの依存をrequirements.txtを書く.

numpy
Pillow

ライブラリを使った処理を追加(確認用)

ここでは,ライブラリを使った処理の例として,ライブラリのバージョンを取得してレスポンスに追加する.

import json

# インストールした依存をインポート
import numpy as np
import PIL.Image

import PIL
def hello(event, context):
    # ライブラリのバージョンを取得
    dependencies = {
        "numpy": np.__version__,
        "Pillow": PIL.__version__
    }
    
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event,
        "dependencies": dependencies
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

デプロイ

以下のコマンドでLambda関数をデプロイする.

# デプロイ
sls deploy --aws-profile <profile_name>

# 削除
sls remove --aws-profile <profile_name>

実行

以下のコマンドでデプロイされたLambda関数を実行する.

sls invoke -f hello

以下のように出力されれば成功

{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}, \"dependencies\": {\"numpy\": \"1.22.3\", \"Pillow\": \"9.0.1\"}}"
}

Discussion