amplify api/function で Python を使ったときに外部ライブラリをデプロイする方法

# はじめに

AWS Amplify の api / function (Lambdaのプログラム言語) として、Python は利用可能である。 
ちょっと探すのに手間取るが、セットアップの方法は以下に書いてある。

https://docs.amplify.aws/guides/api-rest/python-api/q/platform/js

なお、テンプレートとして作成される `index.py` をそのままデプロイするとエラーになる罠がある。 原因はレスポンス形式なので、上記チュートリアルを参考にレスポンスに項目を足すこと。

さて、このチュートリアルでは非常に単純なものだけを利用している。 しかし、実際に Python 内では外部のライブラリを使いたい。 その場合、どのようにすれば Lambda 関数に含まれるのかが分からず、また、検索方法が悪かったのか見つけられなかったため、具体的な方法の２パターンをメモする。


## 方法1. Pipenv でインストールする

Chalice では、deploy コマンド実行時にプロジェクト内にある requirements.txt ファイル内に記載のあるライブラリを deploy 時に pip で落としてきて、zipで固めて、このコードをデプロイするという方法が採られていた。 そのため、ここでも同じようなものではないかとあたりをつけてみると、

```bash
$ cd [プロジェクト]/amplify/backend/function/[関数名]
$ ls
Pipfile  amplify.state  dist  function-parameters.json  parameters.json  pytests-cloudformation-template.json  src
```

となり、`Pipfile` が存在する。 これは pipenv で利用する際に利用する設定ファイルを保存しておくものである。 そのため、このディレクトリで `pipenv install [実際に利用するライブラリ]` を実行し、ライブラリをインストールし、その後に `amplify push` でデプロイした。
その結果、アップロードした Lambda 関数内に `pipenv install` したライブラリが含まれた zip ファイルとしてアップロードされた。


## 方法2. Lambda Layer を作成する

方法1. は個別の Lambda に個別に外部ファイルをセットアップする方法である。 Lambda Layer は複数のLambdaで共用するためのファイルをセットにすることができる仕組みである。

AWS Amplify ではリソースの１つとして Lambda Layer を作成することができる。　詳しくは [こちらの記事を参照のこと](https://aws.amazon.com/jp/blogs/mobile/how-to-use-lambda-layers-with-the-amplify-cli/)。 

具体的な手順としては以下のようになる。

```bash
$ cd [amplifyのトップディレクトリ]
$ amplify add function
? Select which capability you want to add: Lambda layer (shared code & resource used across functions)
? Provide a name for your Lambda layer: testlayer
? Select up to 2 compatible runtimes: Python
? The current AWS account will always have access to this layer.
Optionally, configure who else can access this layer. (Hit <Enter> to skip) 
✅ Lambda layer folders & files created:
amplify/backend/function/testlayer

Next steps:
Move your libraries to the following folder:
[Python]: amplify/backend/function/testlayer/lib/python/lib/python3.8/site-packages

Include any files you want to share across runtimes in this folder:
amplify/backend/function/testlayer/opt

"amplify function update <function-name>" - configure a function with this Lambda layer
"amplify push" - builds all of your local backend resources and provisions them in the cloud


# Next Step に従って ライブラリをインストール
$ pip install [必要なライブラリ] -t backend/function/testlayer/lib/python/lib/python3.8/site-packages

# 関数にこの Lambda Layer を使うように更新をかける or 生成時に Layer を使うように設定する
$ amplify add api
? Please select from one of the below mentioned services: REST
? Provide a friendly name for your resource to be used as a label for this category in the project: test
? Provide a path (e.g., /book/{isbn}): /test
? Choose a Lambda source Create a new Lambda function
? Provide an AWS Lambda function name: layertest
? Choose the runtime that you want to use: Python
Only one template found - using Hello World by default.

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? Yes
? Do you want to access other resources in this project from your Lambda function? No
? Do you want to invoke this function on a recurring schedule? No
? Do you want to configure Lambda layers for this function? Yes
? Provide existing layers or select layers in this project to access from this function (pick up to 5): testlayer
? Select a version for testlayer: 1
(後略)

# 実際に反映
$ amplify push
```

ちゃんと選択で Python を選び、Lambda Layer を使うから必要なものを選択すること。
なお、Layer を作るときに Layer のアクセス権限を選択する場面があるが、デフォルトで自分自身のアカウントでは利用可能なので、どの選択肢も選ばずに先に進むとよい。

このようにすることで、Lambda Layer に共通ライブラリをインストールして、複数の Lambda 関数で使いまわすことが可能となる。