LambdaのRuntime.ImportModuleError: Unable to import module ‘lambda_function’: No module named ‘lambda_function’ Tracebackというエラーに遭遇したときの対処方法

2023.06.27

Lambda関数を作成してテストを実行したときに「Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'lambda_function' Traceback」というエラーが発生しました。
その時に確認した部分をブログに残します。

エラーが発生する前に行っていたこと

動作確認用にマネジメントコンソールからPython 3.10のLambda関数を作成していました。
Lambda の開始方法

Lambda関数作成後にローカルで作成したコードをzipにしてアップロードを行いました。
Lambda 関数の .zip ファイルアーカイブとしてのデプロイ

コードを作成していた環境はWindows10でzipに圧縮したのも同じ環境で行っています。
フォルダ構成は以下のようになっています。

C:.
\---lambda
        lambda_function.py

普段はLinuxでzipコマンドを使用して圧縮するかAWS SAMやS3にzipファイルを置いてCloudFormationでデプロイするのですが、少し急ぎだったので意識せずにフォルダごとzip圧縮してしまったのが原因に繋がっていました。
zipはPowerShellで以下のコマンドを実行しました。

compress-archive フォルダ名 圧縮後のフォルダ名

エラーが発生したときにやったこと

まずエラーの原因を特定する必要がありました。
エラーを読むとライブラリのインポートエラーなのでレイヤー周りかと思いましたが、「No module named 'lambda_function'」と出ていたので違うと判断しました。
lambda_functionが読み込めないとなるとハンドラーの設定周りが怪しいと考えました。
ただし今回はLambdaの作成はマネジメントコンソールから行っているためデフォルトだと「lambda_function.lambda_handler」となっておりコードのファイル名もハンドラーにしている関数の名前にも問題はありませんでした。
Python の Lambda 関数ハンドラー

Lambda 関数の作成時に指定される Lambda 関数ハンドラー名は、以下から取得されます。

  • Lambda ハンドラー関数が配置されているファイルの名前

  • Python ハンドラー関数の名前

関数ハンドラーには任意の名前を付けることができますが、Lambda コンソールのデフォルト名は lambda_function.lambda_handler です。この関数ハンドラー名には、関数名 (lambda_handler) と、ハンドラコードが保存されているファイル (lambda_function.py) が反映されます。

改めてファイル名を確認していたところLambda関数のディレクトリ構成がおかしいことに気が付きました。
以下の画像のようにlambdaディレクトリの下にlambda_function.pyが配置されていました。
この時点で私の想定ではルートディレクトリは以下にlambda_function.pyが配置されていると認識していたので原因はこれではないかと当たりを付けました。

エラーの修正

エラーの修正方法として、コードのファイルだけを選択して圧縮後アップロードしなおす方法と、ハンドラーの設定を変更する2点があります。
修正方法はどちらを選択してもよいのですが、ちゃんとした検証環境であればアップロードしなおす方がよいかと思います。

圧縮後アップロードしなおす方法

以下のコマンドをPowerShellで実行することでフォルダ内に入っているファイルを対象に圧縮してくれます。

compress-archive フォルダ名/* 圧縮後フォルダ名

圧縮後以下のドキュメントの手順でアップロードします。
関数コードの更新
アップロードするとlambda_function.pyがルートディレクトリに配置されていることが分かります。

ルートディレクトリに配置されていることを確認したらテストなどを実行してエラーが出なくなることが確認できます。

ハンドラーの設定を変更する

こちらの方法は以下のドキュメントの手順で変更を行います。
Python の Lambda 関数ハンドラー

現状「lambda_function.lambda_handler」という設定になっています。
これをディレクトリの構成に合わせて「lambda/lambda_function.lambda_handler」に変更します。

Lambda関数のコードタブを開いてランタイム設定の編集をクリックします。

画面が遷移したらハンドラを「lambda/lambda_function.lambda_handler」に変更して保存をクリックします。

ハンドラーの設定を変更したらテストなどを実行してエラーが出なくなることが確認できます。

さいごに

Lambdaハンドラー周りの設定はあまり触ることが無かったので良い機会でした。
zipでアップロードするよりもAWS SAMを毎回使用するようにすればこのようなミスは減ると思います。