概要
今回は、LambdaでRuntime.ImportModuleErrorが発生した時の対処方法をまとめます。LambdaでImportに関する情報は典型的かもしれませんが、私の場合はインターネット上の情報だけではエラーを解決できず、調査に時間が掛かりました。今後の方のために、本記事にまとめたいと思います。
本記事では、先ずRuntime.ImportModuleErrorを対処するための3つのポイントを記載しております。
そして、ベースとなるLambdaの開発環境構築からLambda関数にデプロイパッケージをデプロイするまでの手順をやさしく説明しております。開発環境は、EC2 に、Amazon Linux2のインスタンスを起動した環境です。言語はPython を使用します。Lambdaで開発を始めるエンジニアの参考にしてください。
Runtime.ImportModuleErrorの対処方法
今回、初めてLamndaに標準以外のライブラリを使用しました。後にご紹介する開発環境を構築し、デプロイパッケージを作成したにも関わらず、下記のエラーとなり、Lambdaが実行できません。
[ERROR] Runtime.ImportModuleError: Unable to import module ‘lambda_function’: No module named ‘pyminizip’
以下に、Runtime.ImportModuleErrorの対処方法をまとめます。ポイント1、ポイント2はインターネット上の他資料にも記載がありましたが、今回はポイント3にハマっておりました。詳細は、後述のLambdaにコードをデプロイする3つのポイント を参照ください。
ポイント1 : 開発環境で、Lambdaで使用する(標準以外の)ライブラリを追加したデプロイパッケージ(ZIPファイル)を作成する。
ポイント2 : デプロイパッケージをアップロードした後、Handler名を指定する必要あり。Handler名は、「コードのファイル名.Handlerのメソッド名」とする。
ポイント3 : 開発環境に合わせて、ランタイムのバージョンを指定する必要あり。
Lambda開発環境の構築方法
今回は、Amazon Linux2のインスタンスに環境構築を行います。その他のMac、WSL(Windows Subsystem for Linux)+ Ubuntuでも環境構築は可能です(多少手順が変わります)。
今回、開発環境にAmazon Linux2を使用する理由は、Lambdaと同じAWSアカウント内に起動したAmazon Linux2を使用することで、IAMロールなどの環境依存の確認も合わせて行うことができるからです。
先ず、PythonでAWSリソースにアクセスするための、boto3ライブラリをインストールします。必須ではありませんが、事前準備としてpipのアップグレードを実施しています。rootでpythonを実行する場合は、必要に応じてsudo を付けてください。
$ pip install --upgrade pip
$ pip install boto3
$ pip list
Package Version
--------------- --------
boto3 1.9.143
botocore 1.12.143
docutils 0.14
jmespath 0.9.4
pip 20.1
python-dateutil 2.8.0
pytz 2019.1
s3transfer 0.2.0
setuptools 39.0.1
six 1.12.0
urllib3 1.24.3
次に、この後の検証で使用するライブラリ(pyminizip )のインストールに必要なパッケージをインストールします。こちらは、sudoが必要ですね。
$ sudo yum install -y gcc zlib-devel
$ yum list installed gcc zlib-devel
次は、使用したいライブラリ(pyminizip )をインストールします。こちらもrootでpythonを実行する場合は、必要に応じてsudo を付けてください。
$ pip install pyminizip
Defaulting to user installation because normal site-packages is not writeable
Collecting pyminizip
Downloading pyminizip-0.2.4.tar.gz (258 kB)
|????????????????????????????????| 258 kB 12.7 MB/s
Could not build wheels for pyminizip, since package 'wheel' is not installed.
Installing collected packages: pyminizip
Running setup.py install for pyminizip ...
Successfully installed pyminizip-0.2.4
$ pip list
Package Version
--------------- --------
boto3 1.9.143
botocore 1.12.143
docutils 0.14
jmespath 0.9.4
pip 20.1
pyminizip 0.2.4
python-dateutil 2.8.0
pytz 2019.1
s3transfer 0.2.0
setuptools 39.0.1
six 1.12.0
urllib3 1.24.3
私の場合は、Pythonのソースと同じカレントディレクトリにもライブラリをインストールします。次のステップで行うデプロイパッケージの作成に使用します。
$ cd work-dir
$ pip install pyminizip --target .
Collecting pyminizip
Using cached pyminizip-0.2.4.tar.gz (258 kB)
Could not build wheels for pyminizip, since package 'wheel' is not installed.
Installing collected packages: pyminizip
Running setup.py install for pyminizip ...
Successfully installed pyminizip-0.2.4
$ ls
lambda-s3-make-passwdzip.py pyminizip.cpython-36m-x86_64-linux-gnu.so
pyminizip-0.2.4-py3.6.egg-info
Lambdaにコードをデプロイする3つのポイント
ポイント1: デプロイパッケージの作成
前述の環境構築の手順で、開発環境にLambdaで使用する標準以外のライブラリをインストールしたかと思います。開発したソースとカレントディレクトリにインストールしたライブラリをアーカイブしたデプロイパッケージを作成します。ここでのポイントは、上位のディレクトリをZIP圧縮するのではなく、カレントディレクトリ内のファイルのみをZIP圧縮することです。
念のため、unzip -l コマンドを使用し、ZIPファイルを展開せず中身を確認します。
$ cd work-dir/
$ zip -r ../lambda-s3-make-passwdzip.zip .
adding: pyminizip.cpython-36m-x86_64-linux-gnu.so (deflated 62%)
adding: pyminizip-0.2.4.dist-info/ (stored 0%)
adding: pyminizip-0.2.4.dist-info/top_level.txt (stored 0%)
adding: pyminizip-0.2.4.dist-info/WHEEL (deflated 3%)
adding: pyminizip-0.2.4.dist-info/METADATA (deflated 61%)
adding: pyminizip-0.2.4.dist-info/RECORD (deflated 35%)
adding: pyminizip-0.2.4.dist-info/INSTALLER (stored 0%)
adding: lambda-s3-make-passwdzip.py (deflated 50%)
$ unzip -l ../lambda-s3-make-passwdzip.zip
Archive: ../lambda-s3-make-passwdzip.zip
Length Date Time Name
--------- ---------- ----- ----
439880 05-11-2020 00:46 pyminizip.cpython-36m-x86_64-linux-gnu.so
0 05-11-2020 00:46 pyminizip-0.2.4.dist-info/
10 05-11-2020 00:46 pyminizip-0.2.4.dist-info/top_level.txt
104 05-11-2020 00:46 pyminizip-0.2.4.dist-info/WHEEL
2680 05-11-2020 00:46 pyminizip-0.2.4.dist-info/METADATA
502 05-11-2020 00:46 pyminizip-0.2.4.dist-info/RECORD
4 05-11-2020 00:46 pyminizip-0.2.4.dist-info/INSTALLER
1475 05-07-2020 21:33 lambda-s3-make-passwdzip.py
--------- -------
444655 8 files
出来たデプロイパッケージをLambda関数にアップロードします。10MBを超える場合は、S3 経由でアップロードが必要となります。
ポイント2: Handler名を指定する
デプロイパッケージをアップロードした後、Handler名を指定する必要があります。Handler名は、「コードのファイル名.Handlerのメソッド名」となります。デフォルトのHandler名は、lambda_function.lambda_handlerですね。
ポイント3: ランタイムのバージョンを指定する
開発環境に合わせて、ランタイムのバージョンを指定する必要があります。今回、開発環境はPython 3.6 であり、ランタイムがPython 3.7 となっていたためRuntime.ImportModuleErrorが発生しました。
参考資料
元記事はこちら
「LambdaでRuntime.ImportModuleErrorが発生した時の対処 」
お客様のご要望に柔軟に対応いたします。まずはお気軽にご相談ください。
cloudpackは、アイレット株式会社が提供するクラウド支援サービスです。クラウドの導入・構築から運用・保守、技術的な問い合わせまでトータルサポート!
アイレットでは、様々な職種で一緒に働ける仲間を募集しています。
インフラエンジニア、開発エンジニア、クリエイティブ職、営業職など、様々な職種で一緒に働ける仲間を募集しています。アイレットのこと、社員インタビュー、募集職種、福利厚生など、アイレット公式サイト採用情報をご覧ください。