AWS Lambda　その１

# 記載内容
- AWS Lambdaで関数を構築する手順
- AWS Lambdaで環境変数を用いて設定を外部化する手順
- AWS Lambdaで外部ライブラリを使用する手順
- AWS Lambdaレイヤーで共通モジュールを構築する手順

<br>

## AWS Lambdaのサービス概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/303231aa-306f-3675-d579-3d756b7bacc3.png)
- プログラムの実行環境を提供してくれるサービスです。
- スペックと実行時間で料金を支払えばよいため、自前でサーバを用意した場合と比べると、初期費用や運用コストが節約できます。
- 標準で以下のラインタイムに対応しています。
**.net6(C#)、python、Node.js、Ruby、Java、Go**
- 自分で用意したカスタムランタイムを組み込むこともできます。AWSテクノロジーパートナーが提供するカスタムラインタイムもあります。

<br>

## AWS Lambdaで関数を構築する手順

AWSコンソールのLambdaを選びます。トップページの関数の作成を選びます。

ここでは一から作成を選びます。任意の関数名を入力します。ランタイムはここではPython3を選択します。実行ロールはそのままで関数の作成を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/f2e8dd76-b34a-a91e-0f54-4313a032cd31.png)

関数名のフォルダに、１つのpythonファイルが格納される形で作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/0b13a402-673e-14a4-fcb3-c7094f8320df.png)

単純にステータスコードとメッセージのbodyを返すコードが作成されます。
`lambda_handler`がエントリーポイントです。
```python
import json

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

作成した関数のテストが行なえます。テストタブを選択します。
リクエストパラメータを指定できますが、ここでは空のJsonオブジェクトにします。
テストを選択します。実行結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/eb008567-46f1-fa23-bf99-29df3a224c69.png)

実行結果トグルを展開すると以下のことがわかります。
・実行結果は<font color="green">**成功**</font>である。
・初期所要時間　ランタイム外からこの関数がロードされ、実行できる状態にまで持っていくのに107msかかった。
・所要時間　実行時間は1.5msだった。
・課金時間　課金としてカウントされる時間は2ms。
・設定済みのリソースは　Lambdaの実行メモリスペックで128MBである。スペックはメモリでのみ指定が可能だが、メモリが大きくなるとCPUの性能もあがる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/8afacc51-783d-2292-355f-814d2ea6920a.png)

:::note info
料金は `スペックによる時間単価` ✕ `実行時間` で計算される。実行時間が短く抑えられて、なるべく低スペックが良い。なおLabmdaの実行時間は**最大15分**の制限がある。
:::

## AWS Lambdaで環境変数を用いて設定を外部化する手順

コードを修正することなく挙動を変えるには環境変数が使えます。
設定タブを選択肢ペインから`環境変数`を選択します。
`編集`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/e84e338f-e87b-fd3f-25fa-24d17b6739a8.png)

`環境変数の追加`を選択し、キーと値を入力して保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/5837012a-ec04-336f-ce28-0fd0de056576.png)

環境変数を読み込むようにコードを見直します。変更箇所はマーカー部分です。
コードを変更したら`Deploy`をクリックして実行環境に反映させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/07b747b9-4038-750e-7258-98d38ccd5734.png)

`Changes not deployed`の表示が消えたらデプロイ完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/a7d77861-5405-b1a0-5401-4989b967d822.png)

テストします。環境変数に指定した値が出力されているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/583062b8-edd2-58d0-35ab-2483403ac2d6.png)

## AWS Lambdaで外部ライブラリを使用する手順
ローカルマシンで外部ライブラリをインストールしたフォルダを作成し、zip圧縮してアップロードする形でLambda関数を作成します。
以下の例はLinuxコマンドで作成する手順になります。Windows環境の場合は手作業で作成ください。
ここでは外部ライブラリとして日付操作のmomentライブラリを用います。

フォルダを作成しインストール先を指定して、pipコマンドでmomentをカレントにインストールします。
```sh
mkdir mylambda-exlib
cd mylambda-exlib/
pip install moment -t .
```

Lambda本体のファイルはAWSコンソールで編集するので、ここでは空のファイルだけ作成しておきます。
```sh
touch lambda_function.py
chmod 755 lambda_function.py
```

zipに圧縮します。
```sh
zip -r mylambda-exlib.zip ./*
```
:::note warn
Lambda関数では外部ライブラリや本体ファイルが直下に配置されるように、（つまり、サブフォルダがない）圧縮ファイルを作成する必要があります。
:::

AWSコンソールでLambdaの新規作成を選択します。任意の名前を入力しランタイムは外部ライブラリと同じpython3を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/630227f8-d7cc-70be-4451-62ea6bc1ef37.png)

デフォルトのスクリプトファイルが作成されますが、そのままでアップロード元からzipファイルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/77894fff-92db-02f8-60c0-8f96310be587.png)

アップロードファイルに作成したzipファイルを選択して保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/7af4f375-1d72-b61b-8b2f-7b3c0666fbfc.png)

zipファイルが展開されます。外部ライブラリが直下に展開されているのがわかります。
本体のスクリプトファイルに、外部ライブラリを使ったコードを打ち込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/71029aa0-8a61-0c17-d112-8baa25a8ae4a.png)

デプロイしテストします。外部ライブラリmomentを通して、システム日付が取得できているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/17663a9c-a831-854b-5a47-dcea371a6b3d.png)


## AWS Lambdaレイヤーで共通機能を構築する手順
レイヤーとは頻出するコードを、共通モジュールとして登録できる機能です。
関数ではなくレイヤーとして作成し、Lambda関数からimportして使います。

レイヤーはローカルで開発し、zip圧縮してアップロードする形で作成します。

ここでもmomentを使った機能を用いて開発していきます。
フォルダを`python`の名前で作成し、momentをインストールします。
```sh
mkdir python
cd python/
pip install moment -t .
```

:::note warn
レイヤーの場合は`python`というフォルダに収まる形で作成する必要があります。
:::

Lambda本体のコードを作成します。ファイル名は任意です。ここでは`mylambda_layer｡py`とします。
```python
import moment

class CalcDate():

    def getAfterDay(self, _base, addDay):
        day = moment.date(_base).add('days', addDay).format("YYYY-MM-DD")
        print(day)
        return day
```
何日後の日付を取得するモジュールにしました。

`python`フォルダごと圧縮します。
```sh
cd ..
zip -r mylambda_layer.zip python/
```

AWSコンソールでレイヤーを登録します。
レイヤーは左ペインから選択して行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/b1de1e7a-3df7-5c8b-d688-509c69bdf86e.png)

名称はzipファイル名にします。作成したzipファイルをアップロードします。
ランタイムは`python3x`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/3668599e-3b4a-7e40-1000-7f9de4f2e479.png)

作成されます。同じ名称で作成する度にバージョンが上がっていくので、ここではバージョン３となっていますが、初めて作成した場合はバージョン１となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/8782b1d0-c1d4-7f03-f266-a418e4769823.png)

レイヤーを呼び出すLambda関数を作成します。
任意の名前で一から作成で関数を作成し、コードタブの一番下にあるレイヤーの追加を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/e6192c5d-8bf9-2b43-4949-d93291b6ec54.png)

カスタムレイヤーを選択し、作成したレイヤーとバージョンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/13afbaaf-7d78-382e-3530-25f56d83db62.png)

Lambda関数のコードをレイヤーのメソッドを呼び出すコードにします。

```python
import json
import mylambda_layer

def lambda_handler(event, context):
    s = mylambda_layer.CalcDate()
    result = s.getAfterDay('2023-06-08', 2)
    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }
```

テストします。期待した通りになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730273/a95b901e-b8c7-4ff5-7d3a-5ae58cfb6832.png)

## まとめ
AWS Lambdaで関数を作成する、外部ライブラリを使う、レイヤーを使って共通化を開発効率を上げる方法をまとめました。
AWS Lambdaは他サービスとの連携で力を発揮するサービスです。
他サービスと連携する場合は、IAMで適切なアクセス制御を行いセキュリティを高めることができます。
記事としてまとめていきたいと思います。