AWS SAMで好きなベースイメージを使用したコンテナLambdaでPythonを動作させる
概要
先の記事でコンテナLambdaを実行できるようになりました。
ですが、ローカルでいろいろ触っている開発環境がUbuntuなので、できれば同じものを使いたいと思い、Ubuntu 22.04のコンテナイメージを使用してLambdaのHello Worldを実行させてみます。
AWSのLambda用に提供されているコンテナイメージの内容
ECS用なのかもしれませんが、先の記事で実施した手順で作成したSAMのDockerfileでは、
下記のコンテナイメージを使用しています。
1  | FROM public.ecr.aws/lambda/python:3.9  | 
このOSを調べたところAmazon Linux 2のようでした。
1  | $ uname -a  | 
sam-app/hello_world/Dockerfile の中身は以下のとおりです。
1  | FROM public.ecr.aws/lambda/python:3.9  | 
Ubuntuのコンテナイメージに変更する
sam-app/hello_world/Dockerfile のFROMをUbuntuのものに変更してみます。
1  | - FROM public.ecr.aws/lambda/python:3.9  | 
ちなみに、FROM ubuntu:22.04 は、以下の内容のコンテナイメージです。
1  | PRETTY_NAME="Ubuntu 22.04.2 LTS"  | 
以下のように出力され、sam buildが失敗しました。
1  | $ sam build  | 
UbuntuのイメージにはPython3.9が入っていないようなので、
Dockerfile を少し修正して中身を出力させてみます。
1  | FROM ubuntu:22.04  | 
sam build するとDocker Buildのログに以下のように出力されます。
1  | Step 3/4 : RUN apt list --installed  | 
コンテナ用のイメージなので、余計なものは入れてない感じでしょうか、
PythonをインストールするようにDockerFileを修正します。
1  | FROM ubuntu:22.04  | 
sam build してPython3がインストールされたことを確認します。
Python 3.10.6とpip 22.0.2がインストールされました。
1  | Step 4/7 : RUN apt list --installed | grep python  | 
それでは、DockerFileを修正してLambdaのHello Worldをlocal invokeしてみます。
1  | FROM ubuntu:22.04  | 
実行してみましたが、No response from invoke container…と出力されてしまい、正常に処理されませんでした。
1  | $ sam local invoke  | 
awslambdaricを使用してPython用のコンテナイメージを作成する
色々調べてみたところ、AWSが提供しているイメージではないものを使用してPythonを動かす場合、awslambdaricというライブラリをインストールする必要があるようです。
代替のベースイメージから Python イメージを作成します
下記のページのUsageに従ってDockerFileを修正してみます。
AWS Lambda Runtime Interface Client for Python (awslambdaric)
前半のFor Build部分は不要なのかもしれませんが、まずはガイドに沿ってDockerFileを修正します。
1  | # Define custom function directory  | 
途中でビルドに失敗しました
1  | $ sam build  | 
DockerFileの最初のARGが悪さしているようなので、宣言部分を以下のように修正してみました。
1  | # Define custom function directory  | 
今度はpipが無いと言ってきました。
1  | $ sam build  | 
For Build部分にpipのインストールを追加してみます
1  | # Install aws-lambda-cpp build dependencies  | 
ビルドが通ったので、sam local invokeをしてみます。
1  | $ sam local invoke  | 
正常に動作しました。
awslambdaricを使用したコンテナイメージのDockerFile
正常に動作した時のDockerFileは、以下の内容です。
1  | # Define custom function directory  | 
本当に「—-For fuild—-」部分の記述が必要なのかと思い、
削除して必要な記述を移植して試してみました。
1  | # Define custom function directory  | 
こちらのDockerFileでも正常にビルドが通り、local invokeも問題ありませんでした。
1  | $ sam local invoke  | 
awslambdaric の Usageに、「linux2014ホイールをサポートしていない場合は、必要なビルド依存関係もインストールする必要があります」のような記載があるので、使用するOSによっては必要なのかもしれません。
デプロイと動作確認
2023/03/19 追記
デプロイ確認していなかったので追記します。
sam deployコマンドをガイド使用で実行しました。
1  | $ sam deploy --guided  | 
デプロイするかどうかを聞かれるので、yを選択します。
1  | Previewing CloudFormation changeset before deployment  | 
curlコマンドでテストすると、hello worldが返ってきました。
1  | $ curl https://9b3ce2vfxj.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/  | 
環境の削除
最後に、環境を削除します。
コンテナイメージでデプロイしていると、ECRのリポジトリも削除するかどうかを聞かれるようです。
1  | Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y  | 
まとめ
AWSが提供するLambda用コンテナイメージ以外のイメージ(代替イメージ)を使う場合には、依存ライブラリのインストールや、ENTRYPOINTの設定などが必要なことがわかりました。
今回はPython用を作成しましたが、node.js等もそのうち調べてみたいと思います。