AWS Lambdaでpipモジュールを利用する際はランタイムのPythonバージョンに気を付けよう

"事前にモジュールをpip installした環境"と"Lambda ランタイム"のPythonバージョンは合わせましょうという話
2020.04.13

こんにちは、CX事業本部の若槻です。

AWS Lambdaでのpipモジュールの利用において、Pythonバージョンの不一致に起因したエラーに遭遇したのでご紹介します。

前提となる環境・運用

開発で、AWS Lambdaにアップロードするpipモジュールの事前インストールをCI毎にDockerコンテナ上で行う運用をしていました。

具体的には、Amazon Linux AMIをベースイメージとしたコンテナ環境でpipモジュールのインストールを実施する以下のようなDockerfileを利用して、

FROM amazonlinux:2018.03.0.20191219.0

WORKDIR /workdir
RUN yum install -y python36-devel python36-pip gcc

CMD pip-3.6 install pandas -t .

以下のようなコマンドでDockerコンテナ上でPythonコードのデプロイパッケージを作成し、AWS Lambdaにアップロードしていました(実際はCFnなど利用)。この時、Lambdaのランタイムはpython3.6となります。

$ docker build . -t package
$ docker run --rm -v ${PWD}:/workdir package
$ zip -r deploy_package.zip .
$ aws lambda update-function-code \
    --function-name panda_func \
    --zip-file fileb://deploy_package.zip

また、LambdaではpandasモジュールをインポートしてCSVの操作を行うような処理を行っています。

import pandas

def handler(event, context):
    pandas.DataFrame(["0001", "Classmethod, Inc."])
    print('pandas!!!')

ベースイメージのAmazon LinuxをアップデートしたらLambda実行がエラーとなった

先日に、前述のコンテナのベースイメージをAmazon Linux AMIからAmazon Linux 2に変更する対応を行いました。

変更対応ではDockerfileを以下のように変更し、Amazon Linux 2環境上でpipモジュールの事前インストールを行うようにしました。

FROM amazonlinux:2.0.20191217.0

WORKDIR /workdir
RUN yum install -y python3-devel python3-pip gcc

CMD pip3 install pandas -t .

変更後のDockerfileを利用してDockerコンテナ上でPythonコードのデプロイパッケージを作成し、AWS Lambdaにアップロードするようにしました。

するとLambdaの実行が以下のようなエラーとなり落ちるようになってしまいました。

Unable to import module 'lambda_function': Unable to import required dependencies:
numpy: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy c-extensions failed.
- Try uninstalling and reinstalling numpy.
- If you have already done that, then:
  1. Check that you expected to use Python3.6 from "/var/lang/bin/python3.6",
     and that you have no directories in your PATH or PYTHONPATH that can
     interfere with the Python and numpy version "1.18.2" you're trying to use.
  2. If (1) looks fine, you can open a new issue at
     https://github.com/numpy/numpy/issues.  Please include details on:
     - how you installed Python
     - how you installed numpy
     - your operating system
     - whether or not you have multiple versions of Python installed
     - if you built from source, your compiler versions and ideally a build log

- If you're working with a numpy git repository, try `git clean -xdf`
  (removes all files not under version control) and rebuild numpy.

Note: this error has many possible causes, so please don't comment on
an existing issue about this - open a new one instead.

Original error was: No module named 'numpy.core._multiarray_umath'

原因と対処

原因は、"pipモジュールの事前インストールを行ったコンテナ環境"と、"Lambdaランタイム"のPythonバージョンが異なっていたことでした。

変更後のコンテナ上のPythonバージョンを見てみるとPython 3.7.6でした。Lambdaのランタイムバージョンpython3.6とは異なっています。

$ docker run -it package /bin/bash
bash-4.2# python3 -V
Python 3.7.6

どうやらDockerfile内で定義したPython3をインストールするyum install -y python3-devel python3-pip部分でマイナーバージョンまで指定していなかったため、既定でPython 3.7.6が導入されたようです。

今回はPythonバージョンは3.7に上げる方針とし、対処としてLambda側のランタイムpython3.7にしてコンテナ側に合わせる設定変更を行いました。するとLambdaも問題なく実行されるようになりました。

まとめ

"事前にモジュールをpip installした環境"と"Lambda ランタイム"のPythonバージョンは合わせるようにしましょう。

以上