Lambda Layersを使って処理をまとめてみた

## 背景
アカウントAの複数のLambdaから別のアカウントのEC2の情報を取得する実装を行っていて、Lambdaの中がほぼ同じ処理なのでLambda Layersを使ってmodule化してみます
![スクリーンショット 2022-03-22 13.29.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501320/6dd8867f-882c-3f10-3d3d-0310dcb6e3df.png)

 
## 今回話すこと
- Lambda Layersの概要
- Lambda Layersの使い方

## 今回話さないこと
- クロスアカウントロール周り
- Lambdaのコードの解説
- Lambda関数の作成方法

## Lambda Layersの概要
公式には下記のような説明があります
>Lambda レイヤーは、追加のコードやデータを含めることができる .zip ファイルアーカイブです。

簡潔に言うと1つの関数を定義してそれを複数のLambda関数で使うことができるということです。![スクリーンショット 2022-03-22 14.03.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501320/bb2b49ab-d294-9904-3a3b-004c4d72d5de.png)

## 実際にLambda Layersを作成していく

### コードのzip化
```bash
mkidr python 
vi python/test.py
zip -r lambda_layer_test.zip python/
```

下記コードは`test.py`に入力してください
```python
import boto3

def ec2_access(acct_b):
    ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
    SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
    SESSION_TOKEN = acct_b['Credentials']['SessionToken']

    ec2 = boto3.client(
        'ec2',
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )
    return ec2


def ec2_get_list(acct_b):

    ec2_instance_ids =[]
    ec2_instance_names =[]
    
    ec2_data = ec2_access(acct_b).describe_instances()
    for ec2_reservation in ec2_data['Reservations']:
        for ec2_instance in ec2_reservation['Instances']:
            
            instance_tag_name = list(filter(lambda item: item['Key'] == 'Name', ec2_instance["Tags"]))
            if instance_tag_name:
                ec2_instance_names.append(instance_tag_name[0]["Value"])
            

    return {
        'statusCode': 200,
        'body': ec2_instance_names
    }
```

なぜpythonフォルダを作らなければいけないかと思ったとおもいますが
Layresは`/opt`ディレクトに展開されます
pythonを例に出すと`/opt/python`に展開されるのでpythonディレクトリの下にファイルを配置します
公式の記事は[こちら](https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-import-module-error-python/)を参考にしてください


### Lambda Layersを作成

①Lambaの画面からレイヤーを選択して、レイヤーの作成
![スクリーンショット 2022-03-22 14.17.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501320/4d54e357-f33a-cc18-489d-a6a5bb71b62f.png)

②
| 項目 | 値 | 
|:-----------|------------|
| 名前       | キャメルケース        | 
| .zipファイルをアップロード| zipファイルをアップロード      | 
| 互換性のあるアーキテクチャ     | x86_64          | 
| ランタイム         | 今回は3.8を選択(複数選択することも可能)          | 

![スクリーンショット 2022-03-22 14.22.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501320/f54ce638-8fd9-1bc7-65e7-299dd94bc977.png)
そして作成


### Lambda関数からlambda Layersを読み込む
任意のLambda関数を作成する

```python
import test_layer
import boto3

sts_connection = boto3.client('sts')
acct_b = sts_connection.assume_role(
    RoleArn="arn:aws:iam::取得したいec2のアカウント番号:role/LambdaのRole名",
    RoleSessionName="cross_acct_lambda"
)

def lambda_handler(event, context):
    return test_layer.ec2_get_list(instanse_tag_name,acct_b)
```

layersを押してレイヤーの追加を押す

![スクリーンショット 2022-03-22 15.17.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501320/3af6513d-c348-f1c2-e1d6-2d7eaed3afd5.png)

カスタムレイヤーから先程作成したLayersを選択
![スクリーンショット 2022-03-22 15.18.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501320/02482a38-8d5a-dc42-79c4-6ef2a3f72f7e.png)


LambdaのテストをするとEC2がprintされています
```bash
Test Event Name
hoge

Response
{
  "statusCode": 200,
  "body": [
    "dev-ec2-1",
    "dev-ec2-2"
  ]
}

Function Logs
START RequestId: 0c675016-70a4-4501-abfe-f97749dd1585 Version: $LATEST
END RequestId: 0c675016-70a4-4501-abfe-f97749dd1585
REPORT RequestId: 0c675016-70a4-4501-abfe-f97749dd1585	Duration: 1283.40 ms	Billed Duration: 1284 ms	Memory Size: 128 MB	Max Memory Used: 81 MB	Init Duration: 961.56 ms

Request ID
0c675016-70a4-4501-abfe-f97749dd1585
```

！！完！！