Lambdaのエイリアスとバージョンを試してみた

# 背景・目的
なんとなく知っていましたが、あまり使うことはないLambdaのエイリアスとバージョンについて整理します。

# まとめ
下記に特徴をまとめます。

|特徴|説明|
|:--|:--|
|Lambdaのエイリアスとは|・更新可能な関数のバージョンへのポインタ<BR>・エイリアスは、ARNを使用して関数のバージョンにアクセスできる<BR><BR>・新しいバージョンをデプロイする場合、下記の方法がある<BR>　・新しいバージョンを使用するようにエイリアスを更新する<BR>　・2つのバージョン間でトラフィックを分割する
|エイリアスの制限事項|別のエイリアスを参照することはできない|
|エイリアスの仕様|・エイリアスは、最大2つのLambda関数バージョンを指す事が可能<BR>・両方のバージョンに同様の実行ロールが必要<BR>・同様のDead letter queueを持つか、一切持たない必要がある<BR>・両方のバージョンを公開する必要がある。エイリアスは$LATETを参照することはできない|
|呼び出されたバージョンの確認|・CloudWatch Logs<BR>・レスポンスヘッダーの`x-amz-executed-version`|


# 概要
## エイリアス
下記を参考に整理します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-aliases.html

> Lambda 関数のエイリアスを作成できます。Lambda のエイリアスとは、更新可能な関数のバージョンへのポインタです。関数のユーザーは、エイリアス Amazon リソースネーム (ARN) を使用して関数のバージョンにアクセスできます。新しいバージョンをデプロイする場合は、新しいバージョンを使用するようにエイリアスを更新するか、2 つのバージョン間でトラフィックを分割することができます。

- 更新可能な関数のバージョンへのポインタ
- エイリアスは、ARNを使用して関数のバージョンにアクセスできる
- 新しいバージョンをデプロイする場合、下記の方法がある
    - 新しいバージョンを使用するようにエイリアスを更新する
    - 2つのバージョン間でトラフィックを分割する

### イベントソースとアクセス許可ポリシーでの Lambda エイリアスの使用
下記を参考に整理します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/using-aliases.html

> 各エイリアスには一意の ARN があります。エイリアスは関数のバージョンのみを参照でき、別のエイリアスを参照することはできません。関数の新しいバージョンを指すよう、エイリアスを更新できます。

- 別のエイリアスを参照することはできない

### Lambda エイリアスのルーティング設定を作成する
下記を参考に整理します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuring-alias-routing.html

> エイリアスのルーティング設定を使用して、トラフィックの一部を 2 番目の関数バージョンに送信します。たとえば、エイリアスを設定して、ほとんどのトラフィックを既存のバージョンに送信し、トラフィックの一部を新しいバージョンに送信するように設定することで、新しいバージョンを展開するリスクを軽減できます。

- トラフィックの一部を2番目の関数に送信できる
- 既存のバージョンと新しいバージョンにわけることができる

> Lambda は、単純な確率モデルを使用して 2 つの関数バージョン間でトラフィックを分散します。低いトラフィックレベルでは、各バージョンで設定されたトラフィックの割合と実際の割合の間に大きな差異が生じる場合があります。関数がプロビジョニングされた同時実行を使用する場合、エイリアスルーティングがアクティブである間に、プロビジョニングされた同時実行インスタンスの数を高く設定することで、過剰呼び出しを防ぐことができます。

- Provisioned Concurrencyは、エイリアスにも設定できる


> エイリアスは最大 2 つの Lambda 関数バージョンを指すことができます。バージョンは次の基準を満たす必要があります。
> - 両方のバージョンに同じ実行ロールが必要です。
> - どちらのバージョンも、同じ配信不能キュー設定を持つか、配信不能キュー設定がない必要があります。
> - 両方のバージョンを公開する必要があります。エイリアスが $LATEST を指すことはできません。

- エイリアスは、最大2つのLambda関数バージョンを指す事が可能
- 両方のバージョンに同様の実行ロールが必要
- 同様のDead letter queueを持つか、一切持たない必要がある
- 両方のバージョンを公開する必要がある。エイリアスは$LATETを参照することはできない

#### 呼び出されたバージョンの特定
どちらのバージョンが呼び出されたかを特定するには、下記の方法があります。
- CloudWatch Logs
    - STARTログエントリをLambdaが自動的に発信する
- レスポンスのペイロードで、呼び出された関数のバージョンを示す`x-amz-executed-version`がヘッダーに含まれる


## バージョン
下記を参考に整理します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-versions.html

> バージョンを使用して、関数のデプロイを管理できます。たとえば、安定した実稼働バージョンのユーザーに影響を与えることなく、ベータテスト用の新しいバージョンの関数を公開できます。Lambda は、関数を公開するたびに新しいバージョンの関数を作成します。新しいバージョンは、関数の未公開バージョンのコピーです。未公開バージョンの名前は $LATEST です。

- バージョンを使用して、関数のデプロイを管理できる
- 例）βテスト用の新しいバージョンを公開できる


# 実践
## バージョンとエイリアスの確認
下記を参考に試します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-versions.html#configuration-versions-config

### Lambda 関数の作成
1. Lambdaに移動します
1. 「関数の作成」をクリックします
1. 下記を入力し、「関数の作成」をクリックします
    - MyLambdaFunction
    - ランタイム：Python3.13
1. 下記のコードをアップロードします（「Deploy」します）
    ```python
    import json
    
    def lambda_handler(event, context):
        # TODO implement
        return {
            'statusCode': 200,
            'body': json.dumps('Hello from version 1')
        }
    ```
1. 「Test」をクリックし、動作を確認します。想定した結果が返されました
    ```json
    Status: Succeeded
    Test Event Name: (unsaved) test event
    
    Response:
    {
      "statusCode": 200,
      "body": "\"Hello from version 1\""
    }
    ```
### バージョンの発行
1. ①「バージョン」タブ、②「新しいバージョンを発行」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/20b7935c-c17b-a86f-d69f-66279d4bf834.png)

1. ポップアップが表示されるので、説明を書いて「発行」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2a5c2765-9579-81dc-6de5-f24b2d91b1ee.png)

### エイリアスの作成
1. ①「エイリアス」タブ、②「エイリアスを作成」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/bb51621d-74fb-ca45-5fc9-8e101c7a1bd6.png)

1. 下記を入力し、「保存」をクリックします
    - 名前：任意（ここではprd）
    - バージョン：1
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/540ca81b-74e4-584c-2c96-6a678df2a04b.png)

1. エイリアスの画面で「テスト」タブをクリックし、「テスト」をクリックします。想定通りの結果が返されました
    ```json
    {
      "statusCode": 200,
      "body": "\"Hello from version 1\""
    }
    ```

### コードの更新と新バージョンの発行
1. 下記のようにコードを修正し、「Deploy」をクリックします
    ```py
    import json
    
    def lambda_handler(event, context):
        # TODO implement
        return {
            'statusCode': 200,
            'body': json.dumps('Hello from version 2')
        }
    ```
1. テストを実行します。想定通りの結果が返されました
    ```json
    {
      "statusCode": 200,
      "body": "\"Hello from version 2\""
    }
    ```
    
1. 「バージョン」タブをクリックします
1. 「新しいバージョンを発行」をクリックします
1. 2つのバージョンが作成されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/10753ea7-3482-556f-99e8-706f9b483968.png)

### エイリアスの更新
1. ①「エイリアス」タブ、先ほど作成した②エイリアス「prd」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/1f7b6e3b-291b-09c7-b3bd-aaa7bd5a9735.png)
1. 「編集」をクリックします
1. バージョンを「2」に変更し、「保存」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ab2a72bd-c03e-6338-c73f-6b7dcda2066f.png)

### 動作確認
1. 「テスト」タブをクリックし、「テスト」を実行します。切り替わりました
    ```json
    {
      "statusCode": 200,
      "body": "\"Hello from version 2\""
    }
    ```

## ルーティングの確認
下記を基に試します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuring-alias-routing.html

### エイリアスの設定
現在、エイリアスで参照しているバージョン「2」に対して、あらたに「1」を設定します。

1. 「エイリアス」タブ、エイリアス名「prd」をクリックします
1. 「編集」をクリックします
1. 下記を入力し、「保存」をクリックします
    - ①：追加のバージョン：1
    - ②：重み：20%
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b26a4184-1129-553b-f269-3f2ee4eb1283.png)

### 動作確認
1. 何回か「テスト」をクリックします。ランダムに１が表示されました
    ```json
    {
      "statusCode": 200,
      "body": "\"Hello from version 1\""
    }
    
    {
      "statusCode": 200,
      "body": "\"Hello from version 2\""
    }
    ```
1. CloudWatch Logsに移動します
1. バージョンごとにログストリームが作成されるようです
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/24d5f80b-fcf4-93c1-a67e-37cb2a9e6094.png)

1. バージョン1の結果は下記のとおりです
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f27739ba-4382-726c-c74a-7e1eca40c695.png)

1. バージョン2の結果は下記のとおりです
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b8baecf0-adb3-debe-d8d2-4ab1a4fdf943.png)

## 考察
今回、Lambdaのエイリアスとバージョンについて簡単に整理し、動作確認を行いました。
これらを適切に活用することで、Blue/GreenデプロイやCanaryデプロイを効率的に実現できると感じました。


# 参考


https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/using-aliases.html

https://dev.classmethod.jp/articles/lambda-blue-green/

https://dev.classmethod.jp/articles/aws-lambda-blue-green-deployment-made-easy/