Python
AWS
lambda

AWS LambdaでPythonがサポートされたので試してみた

More than 3 years have passed since last update.

はじめに

AWS LambdaでNode.js、Javaに続いて2015.10.8からPython2.7がサポートされました。これにより、これまでbotoを使って書いたPythonのコードをLambdaで使用することができるようになりました。早速、試してみましたのでポイントをまとめます。

Name

Lambdaで管理する名前です。Lambdaで動作させるPythonのモジュール名ではありません。

Code

Pythonではひとつのファイルはひとつのモジュールです。ファイル名はモジュール名.pyです。
モジュールがひとつの場合はオンラインで編集し、モジュールが複数の場合はzipにまとめてアップロードします。
アップロードする場合は、Management Consoleでブラウザからアップロードするか、S3にアップロードしたファイルを指定します。

zipの作成

モジュールが複数の場合、zipにまとめます。重要なポイントが2点あります。

zip作成のポイント

  • zipの最上位にモジュールがくるように圧縮します。
    • 良い例:オプションなしでunzipしたときにカレントディレクトリにファイルが展開される
    • 悪い例:オプションなしでunzipしたときにディレクトリが作成されてその下にファイルが展開される
  • importするサードパーティモジュールを含めます。
    • 標準モジュールのほかにpip installして自分のコードからimportしているモジュールがある場合、その依存関係も含めてzipに含めます。
    • boto 3はzipに含める必要はありません。特定のバージョンのbotoを使いたい場合はzipに含めます。

zip作成コマンド

Pythonのコードがあるトップレベルのディレクトリにcdしてzip -r filename.zip *します。myModuleDirというディレクトリの下にコードがある場合の例を示します。
zipのファイル名はルールがありません。

bash
$ cd myModuleDir
$ ls
myCode1.py
myCode2.py
...
$ zip -r ~/myLambdaFunction.zip *

サードパーティモジュールをzipに含めるには

pip install <modulename> -t <myModuleDir>でPythonのコードがあるトップレベルのディレクトリにインストールします。
pip install-tオプションでインストール先を指定するとエラーになってしまう場合があります。調べた中ではlib64にインストールされる場合に発生しissueにもあがっているようですが、2015.10時点でAmazon Linuxにyum install python27-pipした場合はこの不具合があります。私が試した中ではlxmlが該当します。この場合は-tオプションをつけないでインストールしたモジュールを単純にコピーするだけで動きました。
Python2.6のモジュールをコピーしたらエラーになりましたので、Python2.7でpip installします。

$ cp -R /usr/local/lib64/python2.7/site-packages/lxml <myModuleDir>

Blueprint

Lambdaから利用するAWSのサービスや、プログラミング言語ごとに簡単にスタートできるテンプレートです。例えば、hello-world-pythonを選択するとPythonでLambdaを簡単に始めることができます。

Handler

Blueprintを選択した場合、コードに記述されたハンドラが選択されています。
既存のPythonモジュールを再利用したい場合は、if __name__ == '__main__':を'def lambda_handler(event, context):'に置き換えて、Lambdaでこのハンドラを指定します。
もしくは既存のモジュールを編集したくない場合は、既存のモジュールをimportしてハンドラを記述したラッパーモジュールを作成します。

Role

実行するLambdaのインスタンスにRoleを割り当てます。AWS Management Consoleで作成、選択できるテンプレートから始めて、必要に応じて権限を編集します。
Roleが正しく設定できていれば、Security Credential(アクセスキー)の設定は必要ありません。

Memory

128MBから1536MBまで段階的に選択できます。実行すると最大消費メモリがコンソールに表示されます。

Timeout

秒単位で設定することができます。今回のアップデートで最大5分間まで設定できるようになりました。Timeoutの時間を超えるとプログラムは強制終了します。

Log

コンソールにも表示されますが、CloudWatchのログに自動で記録されています。

Appendix A. References