AWS Lambda Layersを用いてLambda関数から外部ライブラリを読み込む。Amazon Linux 2のPython環境も整います。（Python3.6、Anaconda）

AWS Consoleにログインし、EC2からAmazon Linux 2を立てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/b8caf336-5363-8d65-7be3-6bab894387cd.png)
インスタンスタイプは~~t2.micro~~で、確認と作成ボタンをクリックします。※後述しますが、t2.mediumにしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/abe92788-6e05-5eaa-7d08-a18c84ad970d.png)
セキュリティーグループは各自で設定してください。SSH接続用に22番ポートを開けておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/d8c8db54-c0cd-c729-fe52-5214d610ba03.png)
既存のキーペアを選択、なければ新規作成してください。SSH接続する際に必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/4a48d9e4-080f-27e0-7314-5dd1cb074c70.png)
インスタンスの作成中です。インスタンスの表示をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/878b9146-40ba-8cde-3cb6-7be8c3cbdcb0.png)
インスタンスの状態がrunning、ステータスチェックが2/2のチェックになったら完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/526407bc-af27-8e98-30b8-7cf6b77cda45.png)
インスタンスの作成が完了したら、IPv4パブリックIPをコピーして、PuTTYからSSH接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/b6c22d2e-c8c5-1649-4032-f7cb42597abd.png)
PuTTYを開いて、Host NameのところにIPアドレスを入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/353da026-69ce-20c7-7477-fe39cde02226.png)
Connection->SSH->Authからキーペアを選択します。PuTTYgenを用いて、.pemから.ppkに変換したものを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5b4ad072-fa35-2675-6311-69cfd4a2fabf.png)
はいをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/a8fd15c7-4f58-ce9c-1480-1dfd72e62f35.png)
ec2-userでログインできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/dde503b1-a9ac-713b-3003-8d495960d2c2.png)

ログインしたら、Pythonのバージョンを確認します。いまだにPython2系がデフォルトになっているようです。

~~~
$ python
Python 2.7.16 (default, Dec 12 2019, 23:58:22)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
~~~

Anacondaをインストールします。AnacondaのサイトからダウンロードURLをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/0067c2e3-e93b-3350-0e1b-895084038129.png)

ダウンロードURLに対してwgetし、bashでインストールします。

~~~
$ wget https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh
$ bash Anaconda3-2019.10-Linux-x86_64.sh
~~~

Enterで規約を読み、yesを入力。Enterでインストール開始。

~~~
Please answer 'yes' or 'no':'
>>> yes

Anaconda3 will now be installed into this location:
/home/ec2-user/anaconda3

  - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below
~~~

~~~
Unpacking payload ...
  0%|   | 0/291 [00:00<?, ?it/s]
~~~

で止まったままになってしまった。

t2.mediumでできるらしいので、インスタンスの停止、インスタンスタイプの変更を行います。
[current latest miniconda sh installer for linux hangs on Unpacking payload step #9345](https://github.com/conda/conda/issues/9345)

Anacondaのインストールができたら、Python3.6環境を作成します。

~~~
$ /home/ec2-user/anaconda3/bin/conda create -n py36 python=3.6
$ /home/ec2-user/anaconda3/bin/conda init 
~~~

インスタンスを再起動し、py36環境でpythonフォルダにライブラリをインストールします。

~~~
$ conda activate py36
$ mkdir python
$ pip install -t ./python requests
$ pip install -t ./python ulid-py
$ pip install -t ./python pillow
$ pip install -t ./python numpy
$ pip install -t ./python opencv-python
$ pip install -t ./python opencv-contrib-python
$ pip install -t ./python pandas
$ pip install -t ./python matplotlib
$ pip install -t ./python folium
~~~

pythonフォルダをzip化します。

~~~
$ zip -r GachiLayers.zip python
~~~

zipファイルをS3へアップロードするために、awscliの設定とboto3をインストールします。

~~~
$ pip install awscli
$ pip install boto3
~~~

AWS Console の IAM からユーザーを作成し、AWS Access Key と Secret Access Key を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/723bdcb7-dcda-f98d-1398-747e91a15e0e.png)

AmazonS3FullAccessのアクセス権限を与えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/59bd134d-fc39-039a-d121-b3f7575a7df5.png)

タグは特になし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/32609cbc-63ed-5329-3cbd-f5f6d0f23f29.png)

確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/fa0e191b-dae2-e2a9-819c-c9e822b3e9a1.png)

作成に成功したら、aws configure に必要なAWS Access Key と Secret Access Key を取得できるので、大事に保管しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/567a9c29-2e3a-820d-7274-613cb9b02cad.png)

AWS Configureの設定、AWS Access Key と Secret Access Key を入力します。

~~~
$ aws configure
AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: json
~~~

ZipファイルをS3へアップロードするためのPythonプログラムを作成します。S3バケットを新規作成しておくこと。

~~~
$ vi upload.py
~~~

~~~python
import boto3

filename = 'GachiLayers.zip'
s3 = boto3.resource('s3')
obj = s3.Object(<INSERT YOUR BUCKET NAME>, filename)
response = obj.put(Body = open(filename, 'rb'))
~~~

実行します。

~~~
$ python upload.py
~~~

S3にアップロードされていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/272cbdd5-2053-3504-a5de-6b8cf0ae1582.png)

AWS Console から Lambda を開き、Layersからレイヤーを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/df96ca5c-0a84-b8c0-77d8-66d8d450b68d.png)

作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/37ee5199-ac79-aea7-7d0e-018e0139457a.png)

Lambda関数を作成（ランタイムはPython3.6）し、Layerを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/79231095-404c-ffe3-73b1-d76b23330eb0.png)

作成したレイヤーを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/583b6762-a741-7eea-9190-e5d9467f57c5.png)

Lamda関数を編集して、ライブラリが読み込まれていることを確認しましょう。

~~~python 
import json
import requests
import ulid
from PIL import Image 
import numpy as np
import cv2
import pandas as pd 
import matplotlib.pyplot as plt
import folium
from folium import plugins

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
~~~

テストイベントを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/7930feda-f7d8-fac1-ba2c-80bb682cd861.png)

実行できれば、ライブラリが読み込まれているはずです。

~~~
Response:
{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}
~~~

お疲れ様でした。終わったらインスタンス消してもいいです。