【データ基盤構築/AWS】Lambda Layerを使ってLambdaでpandasライブラリを使用する方法

# 今回の課題
AWS Lambdaでpandasライブラリを使用したかった。
それにあたり、pandasが入った自作のLambda Layerを使用してLambdaを実行したのだが、
エラーが発生してしまったので解決する手順を記事にした。


## 躓いた箇所

以下の手順でLayerを作成して、Lambdaを実行してみた。
すると、依存関係系のエラーが発生してしまった。

### Layerを作成した手順
1. ローカルに`python`フォルダを作成
1. `python`フォルダ内で、`$ pip install -t . pandas`コマンドを実行してpandasをインストール
1. `$ zip -r9 layers.zip`コマンドを実行して`python`ファイルをzipファイルに圧縮
1. zipファイルをLayer作成画面でアップロード![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/f5612627-ab67-26b3-5d76-f82facb719a7.png)

### 発生したエラー
上記で作成したLayerをLambdaに設定してLambdaを実行してみたところ、
「Numpyのインストール方法に問題がある。」といった内容のエラーが発生してしまった。
```
Test Event Name
test

Response
{
  "errorMessage": "Unable to import module 'lambda_function': Unable to import required dependencies:\nnumpy: \n\nIMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!\n\nImporting the numpy C-extensions failed. This error can happen for\nmany reasons, often due to issues with your setup or how NumPy was\ninstalled.\n\nWe have compiled some common reasons and troubleshooting tips at:\n\n    https://numpy.org/devdocs/user/troubleshooting-importerror.html\n\nPlease note and check the following:\n\n  * The Python version is: Python3.8 from \"/var/lang/bin/python3.8\"\n  * The NumPy version is: \"1.25.1\"\n\nand make sure that they are the versions you expect.\nPlease carefully study the documentation linked above for further help.\n\nOriginal error was: No module named 'numpy.core._multiarray_umath'\n",
  "errorType": "Runtime.ImportModuleError",
  "stackTrace": []
}

Function Logs
START RequestId: ************** Version: $LATEST
[ERROR] Runtime.ImportModuleError: 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. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.8 from "/var/lang/bin/python3.8"
  * The NumPy version is: "1.25.1"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

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

Traceback (most recent call last):END RequestId: **************
REPORT RequestId: **************	Duration: 2.21 ms	Billed Duration: 3 ms	Memory Size: 3008 MB	Max Memory Used: 41 MB	Init Duration: 180.67 ms

Request ID
**************
```

## 原因と解決策
調査した結果、**ローカル環境でpandasをインストールしてしまったこと**に問題があることがわかった。
**AWS Lambdaではランタイム毎に実行環境(OS)が異なり、
対応している実行環境上でライブラリをインストールしてLayerを作成する必要がある**ようだった。


Lambdaで動かすpythonは`Amazon Linux`または、`Amazon Linux2`上で動いているため、
pandasをそれらの環境下でインストールしてzipファイルを作成し、そちらを使用してLayerを作成する必要があった。

以下のどちらかの方法で、
`Amazon Linux` or `Amazon Linux2`の環境下でpandasをインストールすることができる。

* 方法1
EC2でAmazon Linuxまたは、Amazon Linux2でインスタンスを立てて、その中で`$ pip install -t . pandas`をする。

* 方法2
LambdaのDockerイメージを使用して、その中で`$ pip install -t . pandas`をする。



### 解決した手順
今回は、方法2で解決することにした。
#### 1)Lambdaの実行環境のDockerイメージを取得する
```cl
$ docker pull amazon/aws-sam-cli-build-image-python3.8
```
#### 2)コンテナを作成する
```cl
$ sudo docker run -it -v $(pwd):/var/task amazon/aws-sam-cli-build-image-python3.8:latest
```
※`-v $(pwd):/var/task`の部分で、ホストマシンのカレントディレクトリ(`$(pwd)`)をDockerコンテナ内の`/var/task`ディレクトリにマウントするように設定している。
　`/var/task`ディレクトリはLambdaのコードが配置されるデフォルトのディレクトリのこと。

#### 3)コンテナ内でpandasをインストールする
pythonディレクトリの中にpandasをインストールして、zipファイル化する。
```cl
bash-4.2# pip install pandas -t ./python
bash-4.2# zip -r python.zip ./python
```
これでDocker環境で作ったファイルがローカルに作られるので、
生成されたファイルをアップロードして、[Layerを作成した手順](https://qiita.com/drafts/7964efd909ef8d1eb931#layer%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%E6%89%8B%E9%A0%86)の通りLayerを作成することで、Lambdaでpandasライブラリを使えるようになった。

# まとめ
自作のLambda Layerを作成する時は、
使用するランタイムの実行環境(OS)と同じOS上でライブラリをインストールしてzipファイル化して、そちらをアップロードしてLayerを作成する必要があるということを学んだ。


#### 参考にした記事
https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html

https://hub.docker.com/r/amazon/aws-sam-cli-build-image-python3.8

https://qiita.com/Yarimizu14/items/52f4859027165a805630

https://docs.docker.com/storage/