Cloud9 上で Lambda を実行する際に “Unable to import module : No module named” エラーが出た場合の対処

2020.05.27

はじめに

AWS Cloud9 上で Lambda ファンクションをローカルで実行する際に Unable to import module 'DemoFunction/lambda_function': No module named 'requests' エラーが出た場合の原因と対処方法を紹介します.

エラーが発生した環境と現象

Cloud9 IDE を使用して Lambda ファンクションを作成しました.
今回、アプリケーション名は DemoApplication, ファンクション名は DemoFunction, ランタイムは Python としました.
以下は自動で生成されたファイルです.

cm-yokota.shinsuke:~/environment $ tree -L 2 DemoApplication/
DemoApplication/
├── DemoFunction
│   └── lambda_function.py
├── __init__.py
├── requirements.txt
├── template.yaml
└── venv
    ├── bin
    ├── include
    ├── lib
    ├── lib64 -> ./lib
    └── local

Lambda ファンクションでモジュールをインストールする場合, 実行ファイルと同じディレクトリにモジュールをインストールするので, 次のコマンドを実行し DemoFunction 以下にモジュールを配置しました.

cm-yokota.shinsuke:~/environment $ cd DemoApplication/DemoFunction/
cm-yokota.shinsuke:~/environment/DemoApplication/DemoFunction $ pip install --target=./ requests
(省略)
Successfully installed certifi-2020.4.5.1 chardet-3.0.4 idna-2.9 requests-2.23.0 urllib3-1.25.9

この状態で, 下記スクリプトをローカル実行したところ, Unable to import module 'DemoFunction/lambda_function': No module named 'requests' エラーが発生しました.

import requests

def lambda_handler(event, context):
    return 'Done'

原因と対処

モジュールのインストール先が間違っていたことがエラーの原因でした.
Cloud9 は Lambda アプリケーション を利用しているため, アプリケーションディレクトリ(今回はDemoApplication/)が Lambda ファンクションの実行ディレクトリになります.
したがって, import requests で requests モジュールを読み込みたい場合はアプリケーションディレクトリ直下にモジュールをインストールする必要がありました.

cm-yokota.shinsuke:~/environment $ tree -L 2 DemoApplication/
DemoApplication/
├── この階層にパッケージ設置
├── DemoFunction
│   └── lambda_function.py
├── __init__.py
├── requirements.txt
├── template.yaml
└── venv
    ├── bin
    ├── include
    ├── lib
    ├── lib64 -> ./lib
    └── local

DemoApplication 以下にモジュールを配置することで正常にファンクションをローカル実行することができる様になりました.