【AWS API Gateway Tips】API Gateway + Lambdaのバージョン管理

# はじめに
API Gateway + Lambdaの構成で、複数バージョンを管理する方法を紹介する。

# 動作確認環境
* AWS API Gateway
* AWS Lambda

# 前提知識
* AWS API Gatewayを作成できる
* AWS Lambdaを作成できる

# 前提条件
* AWS API GatewayでAPIを作成済み
* AWS Lambdaを作成済み
  * Lambdaでバージョンおよびエイリアスを作成済み
    * エイリアス```dev``` : 開発バージョン
    * エイリアス```prod``` : 本番バージョン

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/39d6f4c8-a617-4a69-b025-4153ced3b7bd.png)



# 方法

API単位でステージを作成することでバージョン管理できるようになる。

AWSコンソールで、対象のAPIを選択して、左ペインの「ステージ」を選択する。

ステージが存在しない場合は、「Create stage」ボタンでステージを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/5400c198-04b6-4325-966b-d90bfbd8d3ec.png)

以下のステージの作成画面からステージを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/51b3d56e-2e70-4451-85e9-d58eb99b4ce1.png)

* ステージ名：任意のステージ名（dev、prodなど）
* デプロイ：APIのデプロイバージョンを選択

上記項目を記載して、「ステージを作成」ボタンを押すとステージが作成される。


次にLambda関数のエイリアスをAPI Gatewayに紐づける。

Lambda関数のエイリアスは、Lambda関数のバージョンと紐づいているものとする。詳細については、以下の記事を参照。

https://zenn.dev/amarelo_n24/articles/158a166d832487

このLambda関数のエイリアスを、API Gatewayに紐づけるには、ステージ変数をステージごとに作成して、Lambda関数のエイリアスに指定する。

API GatewayのAPIのステージの設定から「ステージ変数」の「編集」ボタンを押してステージ変数を作成する。

下記の例では、ステージ変数を```alias```として、本番環境のステージ（```prod```）なので、値として、```prod```を設定している。同様にして、開発環境のステージ（```dev```）の場合は、値として、```dev```を設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/28ca0521-dd48-44f8-b3cd-2d6190311d42.png)


作成したステージ変数は、APIの設定から```${stageVariables.<variable_name>}```で参照できる。ここで、```<variable_name>```は任意に設定できるステージ変数名で、後述のLambda関数のエイリアスとする。

:::note ポイント

ステージ変数名で設定する値は、**Lambda関数のエイリアス名と一致させる**必要がある。後述のAPIから参照されるLambda関数の設定に、このステージ変数を使って参照を切り替える。
:::

各APIで、Lambda関数のバージョンへ紐づける処理を行う。

APIの「リソース」からLambda関数と紐づけしたいメソッドを選択し、「統合リクエスト」の「編集」ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/007f944f-6972-4ded-874f-772e200e5857.png)

「Method details」のLambda関数で、呼び出したいLambda関数を選択する。選択後に、Lambda関数の末尾に、```${stageVariables.alias}```を追記する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/19a39ad8-9397-4448-b241-5e18520b372b.png)

「Lambda関数をステージ変数として定義しました。・・・」と警告が出てくる。AWS CLIを使ってポリシーに許可を追加する必要がある。
一度、AWS CLIを開いて、表示された内容をコピーして貼り付ける。　　
次に、```${stageVariables.alias}```となっている箇所を、```prod```に書き換えて、コマンドを実行する。

```bash:本番バージョンの許可
aws lambda add-permission \
--function-name "arn:aws:lambda:ap-northeast-1:123456789012:function:<LambdaFunctionName>:prod" \
--source-arn "arn:aws:execute-api:ap-northeast-1:123456789012:xxxxxxxxxx/*/XXX/<method>" \
--principal apigateway.amazonaws.com \
--statement-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
--action lambda:InvokeFunction
```

以下のような結果となれば成功。
```bash
{
    "Statement": "{\"Sid\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:123456789012:function:<LambdaFunctionName>:prod\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:123456789012:xxxxxxxxxx/*/XXX/<method>\"}}}"
}
```

同様に```dev```に書き換えてコマンドを実行する。

```bash:開発バージョンの許可
aws lambda add-permission \
--function-name "arn:aws:lambda:ap-northeast-1:123456789012:function:<LambdaFunctionName>:dev" \
--source-arn "arn:aws:execute-api:ap-northeast-1:123456789012:xxxxxxxxxx/*/XXX/<method>" \
--principal apigateway.amazonaws.com \
--statement-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
--action lambda:InvokeFunction
```

以下のような結果となれば成功。上手くいかない場合は、AWS CLIのアクセス権やLambda関数名が間違っていないかなどを見直す。

```bash
{
    "Statement": "{\"Sid\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:123456789012:function:<LambdaFunctionName>:dev\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:123456789012:xxxxxxxxxx/*/XXX/<method>\"}}}"
}
```


AWSコンソールに戻り、最後に、右下の保存ボタンを押して完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/48905e7e-8bf7-4668-87b9-9ddfd0270209.png)

複数のメソッドがある場合は、同様の処理を繰り返す。

# まとめ

API Gateway + Lambdaの構成で、複数バージョンを管理する方法を紹介した。APIで複数バージョンを運用したい場合に役立つので参考にしてほしい。


# 参考

https://zenn.dev/amarelo_n24/articles/158a166d832487

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/aws-api-gateway-stage-variables-reference.html

https://dev.classmethod.jp/articles/version-management-with-api-gateway-and-lambda/

https://dev.classmethod.jp/articles/tsnote-lambda-apigw-version-control/