Windowsから外部ライブラリを利用するPythonのLambdaをデプロイしてみる

Windowsから外部ライブラリを利用するPythonのLambdaへデプロイする機会があったので、やり方をご紹介します。ついでにバッチ化します。
2023.04.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Windowsから外部ライブラリを利用するPythonのLambdaへデプロイする機会があったので、やり方をご紹介します。

やっていることは次の公式ドキュメントと同様です。

本ブログでは、この公式ドキュメントの内容に加えて、もうちょっと手順を詳しく解説していきます。

最終的なバッチ

最初にこれからやる作業をまとめたバッチファイルを載せておきます。 これ見て何となくわかるようなら、この先は読まなくても大丈夫です。

deploy.bat

if exist my-deployment-package.zip del my-deployment-package.zip
if exist dist rmdir /s /q dist

pip install --target .\dist -r requirements.txt
copy index.py .\dist\index.py
cd dist
powershell Compress-Archive -Path * -DestinationPath ..\my-deployment-package.zip
cd ..

set AWS_PROFILE=<<YOUR AWS PROFILE>>
set AWS_DEFAULT_REGION=ap-northeast-1
aws lambda update-function-code --function-name deploy-test-lambda --zip-file fileb://./my-deployment-package.zip

前提

python3.9をインストールして、コマンドプロンプトで実行可能にしておいてください。

> python --version
Python 3.9.13

AWS CLI(v2) をインストールして、コマンドプロンプトで実行可能にしておいてください。

> aws --version
aws-cli/2.11.10 Python/3.11.2 Windows/10 exe/AMD64 prompt/off

次のようなPython3.9のLambdaが構築されている前提です。

関数名 ランタイム ハンドラ アーキテクチャ
deploy-test-lambda python3.9 index.handler x86_64

今回はすでに構築されているLambdaに対してデプロイする手順を紹介します。

サンプルプログラムを用意する

まずは、Lambdaで動かす用の外部ライブラリを利用するサンプルプログラムを用意します。 こんな感じの、 requests を使ってLambdaのグローバルIPを取得して返すプログラムを使ってみます。

index.py

import requests

def handler(event, context):
    print(event)

    res = requests.get('https://checkip.amazonaws.com')

    return res.text

ちなみに、 https://checkip.amazonaws.com はAWSが提供している地味なサービスで、アクセスすると接続者のグローバルIPアドレスを返します。詳しくは公式ドキュメントを御覧ください。

必要な外部ライブラリは次のように requirements.txt に記録しておきます。

requirements.txt

requests==2.28.2

そうすると pip を使って外部ライブラリをインストールできます。

> pip install -r requirements.txt

ローカルマシンで動作を確かめたい時は、別途以下のような local-invoke.py を同フォルダに作っておきます。

local-invoke.py

import index

result = index.handler({}, {})

print(result)

次のようにこれを実行すれば、 index.pyhandler 関数を実行でき、ローカルマシンのグローバルIPが表示されます。

> python -B local-invoke.py
{}
XX.XX.XX.XX

現状のフォルダ構成はこんな感じです。

> tree /f /a ..
\---lambda
        index.py
        local-invoke.py
        requirements.txt

デプロイパッケージを作成する

デプロイパッケージを作成する時は、外部ライブラリを含める必要があります。 そのため、次のように pip install のターゲットフォルダを dist(デプロイパッケージ用のフォルダ)に変更してインストールします。

> pip install -r requirements.txt --target .\dist

プログラム本体もコピーして dist に含めます。

> copy index.py .\dist\index.py

デプロイパッケージの中身ができたので、powershellの Compress-Archive を利用してzip化します。

> cd dist
> powershell Compress-Archive -Path * -DestinationPath ..\my-deployment-package.zip

これで、デプロイパッケージは完成です。 現状のフォルダ構成はこんな感じです。

> cd ..
> tree /a /f ..
\---lambda
    |   index.py
    |   local-invoke.py
    |   my-deployment-package.zip
    |   requirements.txt
    |
    \---dist
        |   index.py
        |
        (省略)

デプロイパッケージをLambdaにデプロイする

デプロイパッケージまでできれば、後はLambdaにアップロードするだけです。

マネジメントコンソールのここで、作成した my-deployment-package.zip をアップロードすれば適用されます。

Testボタンを押して、テストイベントを作成できます。テストイベントを適当に作ります。

テストイベント作成後にテストしてみると、Lambdaを実行してLambdaのグローバルIPが表示されます。

AWS CLIを利用すれば、コマンドプロンプトからもアップロードできます。 AWS CLIのプロファイルは適切なプロファイル名を設定してください。 --function-name は関数名を指定します。 今回は deploy-test-lambda という関数名を設定していますが、環境に合わせて変更してください。

> set AWS_PROFILE=<<YOUR AWS PROFILE>>
> set AWS_DEFAULT_REGION=ap-northeast-1
> aws lambda update-function-code --function-name deploy-test-lambda --zip-file fileb://./my-deployment-package.zip

デプロイ作業をバッチ化する

Lambdaのデプロイは開発中に何度もやることになるので、バッチ化して繰り返しできるようにします。

最初に載せていたバッチを再掲します。

if exist my-deployment-package.zip del my-deployment-package.zip
if exist dist rmdir /s /q dist

pip install --target .\dist -r requirements.txt
copy index.py .\dist\index.py
cd dist
powershell Compress-Archive -Path * -DestinationPath ..\my-deployment-package.zip
cd ..

set AWS_PROFILE=<<YOUR AWS PROFILE>>
set AWS_DEFAULT_REGION=ap-northeast-1
aws lambda update-function-code --function-name deploy-test-lambda --zip-file fileb://./my-deployment-package.zip

最初の2行でデプロイパッケージと、distフォルダの中身を削除します。 後は今までやってきたコマンドを順番に実行しているだけです。

これで、バッチを実行すればサクッとLambdaにデプロイできます。

注意点

pipパッケージにバイナリが含まれている等、OS依存の何かが含まれている場合、Windowsでpip installして作成したデプロイパッケージでは、Lambdaでエラーが発生して動きません。

DockerやCodeBuildを使用するなど、AWS Lambdaに合わせた環境(Amazon Linux)でデプロイパッケージを作成することを検討してください。

終わりに

WindowsでPythonのLambdaのデプロイをやってみました。

AWS公式ドキュメントにもやり方は書いてあるのですが、わかりにくそうな部分を詳しく解説しました。

本ブログがどなたかの参考になれば幸いです。