依存関係なしでデプロイした際のAWS Lambda「Runtime.ImportModuleError: No module named requests」を修正する

beginner☁️ AWS2026-03-26| AWS Lambda、Python 3.8 / 3.9 / 3.10 / 3.11 ランタイム、AWS Console・AWS CLI・SAM/Terraform 経由でデプロイ

Error Message

Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'requests'
#lambda#python#レイヤー#デプロイ#依存関係

エラーの内容

Lambda 関数をデプロイしてトリガーすると、CloudWatch Logs に即座に以下のエラーが表示されます:

[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'requests'
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 1, in <module>
    import requests

Lambda は最小限の実行環境で動作しており、サードパーティのパッケージはあらかじめインストールされていません。コード内で import requestsimport pandas、またはPython標準ライブラリ以外のものを呼び出す場合、それらのパッケージを自分でデプロイに含める必要があります。boto3 にも組み込みバージョンがありますが、古い場合があります。特定のバージョンが必要な場合は、それも一緒にバンドルしてください。

なぜこのエラーが発生するのか

.zip ファイルをアップロードする場合でも、コンソールのインラインエディタを使用する場合でも、Lambda は明示的に含めたファイルしか認識しません。ローカルマシンとの接続はありません。pip でインストールしたパッケージは仮想環境の中に存在しており、デプロイの成果物には含まれていないため、Lambda はそれらの存在を知る術がありません。

解決策 1 — 依存関係をデプロイパッケージにバンドルする(最速)

最も手早い解決策:パッケージをプロジェクトフォルダに直接インストールし、すべてをまとめて zip にします。

ステップ 1 — クリーンなプロジェクトフォルダを作成する

mkdir my_lambda
cd my_lambda

ステップ 2 — 依存関係をプロジェクトフォルダにインストールする

pip install requests -t .

-t . フラグは、グローバルの Python 環境ではなく現在のディレクトリにインストールするよう pip に指示します。関数に必要なすべてのパッケージに対してこの操作を繰り返してください。requests==2.31.0 の場合、約 300KB のファイルがフォルダに直接展開されます。

ステップ 3 — 関数ファイルを追加する

# lambda_function.py
import requests

def lambda_handler(event, context):
    response = requests.get("https://httpbin.org/get")
    return {
        "statusCode": response.status_code,
        "body": response.text
    }

ステップ 4 — すべてを zip にまとめる

zip -r function.zip .

重要な点:lambda_function.py はサブフォルダの中ではなく、zip のルートに配置されていなければなりません。Lambda はトップレベルでハンドラを探し、サブディレクトリは検索しません。

ステップ 5 — zip をデプロイする

aws lambda update-function-code \
  --function-name my-function-name \
  --zip-file fileb://function.zip

解決策 2 — Lambda レイヤーを使用する(再利用に適した方法)

requestsboto3 を使用する Lambda 関数が5つある場合、同じパッケージを5つの別々の zip にバンドルするのはスペースの無駄遣いであり、更新も煩雑になります。Lambda レイヤーを使えば、依存関係を一度だけパッケージ化し、必要な任意の関数にアタッチできます。各デプロイの zip を軽量(場合によっては 10KB 未満)に保ちながら、依存関係の更新を一元管理できます。

ステップ 1 — レイヤーのディレクトリ構造を作成する

Python レイヤーは特定のフォルダ構成に従う必要があります。Lambda は python/ 配下のパッケージを探します。それ以外の名前では読み込まれません。

mkdir -p layer/python
pip install requests -t layer/python/

ステップ 2 — レイヤーを zip にする

cd layer
zip -r ../requests_layer.zip python/
cd ..

ステップ 3 — レイヤーを AWS に公開する

aws lambda publish-layer-version \
  --layer-name requests-layer \
  --zip-file fileb://requests_layer.zip \
  --compatible-runtimes python3.9 python3.10 python3.11

出力から LayerVersionArn をコピーしてください。arn:aws:lambda:us-east-1:123456789012:layer:requests-layer:1 のような形式になっています。次のステップで必要になります。

ステップ 4 — レイヤーを関数にアタッチする

aws lambda update-function-configuration \
  --function-name my-function-name \
  --layers arn:aws:lambda:us-east-1:123456789012:layer:requests-layer:1

ステップ 3 でコピーした ARN に置き換えてください。

ステップ 5 — 関数コードをデプロイする(依存関係のバンドルは不要)

# 関数ファイルだけを zip にする — パッケージは不要
zip function.zip lambda_function.py

aws lambda update-function-code \
  --function-name my-function-name \
  --zip-file fileb://function.zip

解決策 3 — AWS SAM または CDK を使用する(CI/CD パイプライン向け)

適切なデプロイパイプラインを持つチームプロジェクトに取り組んでいる場合は、手動での zip 化を完全にスキップできます。requirements.txt を追加するだけで、SAM が sam build 実行時に依存関係のバンドルを自動的に処理してくれます。

# requirements.txt
requests==2.31.0
# template.yaml(関連部分)
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.11
      CodeUri: ./src
      Layers: []  # SAM が requirements.txt から自動的にインストールする
sam build
sam deploy

修正の確認

デプロイ後、関数を呼び出してレスポンスを確認します:

aws lambda invoke \
  --function-name my-function-name \
  --payload '{}' \
  response.json

cat response.json

正常に実行されると以下が返されます:

{"statusCode": 200, "body": "{...}"}

まだ Runtime.ImportModuleError が表示される場合は、最新のログを直接ストリームで確認してください:

aws logs tail /aws/lambda/my-function-name --follow

再デプロイする前に、パッケージが実際に zip の中に含まれているか確認してください:

unzip -l function.zip | grep requests

アーカイブのルートに requests/__init__.py が表示されているはずです。この行が表示されない場合、パッケージは zip に含まれていません。

エラーが繰り返し発生する一般的なミス

  • Python バージョンの不一致: Python 3.11 で pip install を実行しながら Python 3.9 ランタイムにデプロイすると、numpycryptography などのコンパイル済みパッケージが壊れます。ローカルの Python バージョンを Lambda ランタイムと完全に一致させてください。
  • 誤ったディレクトリへのインストール: -t . なしで pip install requests を実行すると、パッケージはプロジェクトフォルダではなくシステムの Python にインストールされます。そのため zip には含まれません。
  • ネストされた zip 構造: 親ディレクトリから zip を作成すると my_lambda/lambda_function.py のような構造になります。Lambda はこの方法ではハンドラを見つけられません。zip を作成する前に必ずプロジェクトフォルダに cd してください。
  • レイヤーのフォルダ名の不一致: Python レイヤーのパッケージは zip 内の python/ 配下に置かれなければなりません。他のフォルダ名を使用すると、Lambda はレイヤー全体を無視します。
  • レイヤーのアタッチ忘れ: レイヤーを公開しても、自動的に関数に紐付けられるわけではありません。update-function-configuration --layers のステップは必須です。見落としやすく、気づきにくいミスです。
  • プラットフォーム固有のホイール: C 拡張を持つパッケージ(numpyPillow など)は Amazon Linux 2 向けにコンパイルされている必要があります。対応する Docker コンテナ内でビルドしてください:docker run --rm -v $(pwd):/var/task public.ecr.aws/lambda/python:3.11 pip install requests -t /var/task/

クイックリファレンス — どの解決策を使うべきか

  • 単一の関数、シンプルな依存関係: pip install -t . でバンドルして zip にする。
  • 依存関係を共有する複数の関数: Lambda レイヤーを使用する。
  • CI/CD を使うチームプロジェクト: requirements.txt と共に SAM または CDK を使用する。
  • 大規模またはコンパイル済みパッケージ(numpy、pandas、Pillow): Lambda ランタイムに合わせた Docker でビルドする。

Related Error Notes