Serverless で Python のパッケージを使った Lambda 関数をデプロイ
目次
Python パッケージを使う、原始的な方法
過去に2回、Serverless Framework を使った Lambda 関数の管理について書きました。
- Serverless Framework による AWS Lambda 関数の管理1 | もばらぶエンジニアブログ
- Serverless Framework による AWS Lambda 関数の管理2 | もばらぶエンジニアブログ
1回目の投稿の際、Python のパッケージを使いたい場合は、以下の通り、Lambda 関数の Python ファイルと同じディレクトリにパッケージをインストールして、それを sls deploy
でパッケージ化&デプロイする方法を紹介しました。
pip install パッケージ名 -t .
「原始的な方法」の問題点
上に挙げた方法には2つの問題があります。
- ディレクトリが汚れる
- pure Python ではないモジュール(コンパイルが必要なモジュール)を使う際に問題がある
それぞれについて簡単に説明します。
ディレクトリが汚れる
例えば、requests
パッケージをインストールすると、requests
が依存している他のパッケージも同じディレクトリにインストールされます。使用するパッケージが増えてくると、ディレクトリが沢山出来て汚いです。
また、Serverless で Lambda 関数を管理するという事は、当然ソースコードも管理しているかと思いますが、それらの Python パッケージはソースコード管理に加える事は望ましくないため、 .gitignore
に入れるなどの方法を取る事になります。パッケージが増えてくると、都度 .gitignore
に追加するのも面倒になってきます。
pure Python ではないモジュールを使う際に問題がある
例えば、Mac で Serverless を使っているとします。pip install
で pure Python でない、コンパイルが必要なモジュールをインストールすると、当然ながら Mac 上でコンパイルされ、Mac 用のバイナリが出来ます。これをそのまま sls deploy
でデプロイしても、Lambda は裏側では Amazon Linux 上で動いているので、バイナリの互換性が無いためエラーになります。
serverless-python-requirements を使った解決方法
上の問題を解決するのが serverless-python-requirements というプラグインです。
具体的な使い方は、実は Serverless のブログサイトに記事があるので、それを読んでもらうと良いかもしれませんが、若干冗長なのと英語なので、本記事でも簡単にまとめます。
How to Handle your Python packaging in Lambda with Serverless plugins
インストール・事前準備
以下の通り serverless-python-requirements をインストールします。
npm install --save serverless-python-requirements
# この後、package.json はコミットしておく
Serverless のプラグインは、それを必要とするプロジェクトでのみインストールすべきだと思うので、-g
はつけない方が良いと思います。
また、同プラグインは内部で Docker を使うため、Docker もインストールしておきます。
設定
serverless.yml に以下の通り記述します。
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true
使い方
requirements.txt
に使いたいパッケージを記載します。例えば以下の通りです。通常の requirements.txt
と同じなので、詳しい説明はしません。
requests==2.18.4
paramiko
後は、sls deploy
をすれば、よしなにやってくれます。
たったこれだけです。
補足
requirements.py
ネットを見ると import requirements
が必要であると書いているページがいくつかありましたが、(昔は必要だったようですが)今は必要ないようです。
以下のようなページです。
- Serverless Frameworkのプラグインを利用した外部モジュールの管理 | Developers.IO
- Serverless Python Requirements で楽をする – Qiita
内部の動作
実際にどうやって動作しているのかは、上述の Classmethod さんのページで細かく解説しているので、そちらを参考にすると良いと思います。
ただ、若干現在の動作と異なるようなので、その部分だけ説明します。
現在は、sys.path
をいじることはしていません。その代わり、sls deploy
の時にローカルの .serverless
に必要なファイルを全て集め、それらをパッケージングしています。
作成された zip ファイルの中身を見てみると、以下のようになっています。
$ unzip -l .serverless/my-lambda-function.zip | awk '{print $4}'
# 出力結果は適当に省略します
Name
----
.libs_cffi_backend/libffi-d7bb31a0.so.6.0.4 # <- バイナリ
(snip)
my-lamda-function.py # <- 自分で作成したファイル
(snip)
requests-2.18.4.dist-info/DESCRIPTION.rst # <- パッケージに含まれるドキュメント
(snip)
requests/__init__.py # <- パッケージ内の Python ファイル
(snip)
requirements.txt # <- 自分で作成したファイル
まとめ
Serverless を使うと、Lambda 関数が簡単に管理できますが、Serverless 単体だと Python の外部パッケージを使う際にいくつかの問題がありました。serverless-python-requirements プラグインを使う事でその問題は解決できるため、Python で Lambda 関数を開発する人にとっては必須のプラグインと言えるでしょう。
コメントを残す