Lambda入門#5 Lambdaと連携したAPI Gatewayのバージョン管理

さぁ、今日もlambdaを触っていきます！

# 参考URL
クラウドメソッドさんの記事を参考にしてやってます。

APIゲートウェイのバージョン管理（lambda連携）
https://dev.classmethod.jp/cloud/aws/version-management-with-api-gateway-and-lambda/

## 前回までのおさらい　lambdaのエイリアス設定

最初の状態ではAPIゲートウェイに紐づいている```$LATEST```の結果が返ってきます。
では、実際に紐づけを行う前に```$LATEST```がどのようになっていて、エイリアスでprodステージとdevステージとの違いが分かるように整理しておきます。

そこでちょっと、おさらいなのですが、lambdaのエイリアスとバージョン管理の方法にも触れておきます。

__１．lambdaでバージョンを作成__

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/00474acb-d2ff-c43d-e23e-2ca566d87660.png)

__２．エイリアスの作成__

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/11f0239e-42df-cded-86db-48202af70d4b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/68de379f-8577-d1b1-dbc6-bbf818120331.png)

どちらも、lambda上のGUIから操作して簡単に作成可能でした。
ちなみに削除する際は「エイリアス」→「バージョン」の順で設定を削除します。
※逆に操作しようとするとエラーが発生します。

ではこれを応用して、APIゲートウェイのバックエンドで動作させるlambdaの関数を本番と開発で分け、かつ、そのバージョン管理も行えるようにしてみようっていうのが、記事の主旨になります。

でちなみにいろいろと操作してたので、4版までバージョン発行を行ってしまったので、少し表示に違和感がありますが、↓のような感じでエイリアスを用意しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/13322dac-cbb1-c7b8-4f7f-4df1e3d6424e.png)

どちらのlambda関数ともに単にバージョンと数字を返すだけの単純な関数が設定されています。
前回の記事にも記載しましたが、prodは固定で変更することはできず、以下の通り、「バージョン1」の値を返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/ddbbcf0d-dd6e-c93d-edec-5ddc5cb320e3.png)

一方、devのほうは「バージョン2」の値を返します。
それから、APIゲートウェイのほうも設定を用意しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/3c2ec79d-3e4b-21d7-dc87-a6540d14247b.png)

まず、リソースは分かりやすく「dev」としておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/3e8a41f7-5654-2f3c-9610-c789618f76d4.png)

次にメソッドはGetの定義を用意しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/73ea1d2e-92a6-030e-12d8-1d2054ff1856.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/f2046c0c-75a7-f1ad-7134-336a8600ae8b.png)

メソッドを用意したら、デプロイしていきましょう！
今回はテストなので、APIキーは流用で構成しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/c25e42ca-a16a-2e7d-6a35-5dbdb4670f8d.png)

スロットリングとかクォータの設定がないのは、前回の記事を踏襲しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/39029a75-d42d-7e1d-13a7-23def15b3d95.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/cf3a2ab3-5dee-fb56-2ab4-f8d3fe727e15.png)

## APIゲートウェイとlambdaのエイリアス設定を連携する

まずはAPIゲートウェイ側の設定を変更していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/2f4aeb4b-8a8b-39b5-d894-33e4382e702a.png)

作成したAPIゲートウェイの[統合リクエスト]をクリックします。
そこで[Lambda関数]に入力している関数名の末尾に以下の変数を追加して保存します。

```bash:追加変数
:${stageVariables.alias}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/8a7ddd38-9f16-faab-501e-5af314f3b6f0.png)

保存すると以下のようにAWSCLIのコマンドが発行されるので、コマンドを控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/98e0799a-53ae-4bfe-37f5-28ac3550ca08.png)

```bash:AWSCLIのコマンド
aws lambda add-permission --function-name "arn:aws:lambda:*******:${stageVariables.alias}" --source-arn "arn:aws:execute-api:*******:*******:kcgilegeu5/*/GET/dev" --principal apigateway.amazonaws.com --statement-id ******* --action lambda:InvokeFunction
```

ただ、このコマンドを実際に実行する際には「dev」と「prod」でlambdaのエイリアスが分かれますので、```"arn:aws:lambda:*******:${stageVariables.alias}"```の```:${stageVariables.alias}```をdevとprodに変更して2回実行する必要があります。

実際に実行してみると以下のような感じでコマンドが戻ってくると思います。

```bash:実行結果
{
    "Statement": "{\"Sid\":\"******\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:******:******:function:cm-kanechanee-APITest01:dev\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:******:******:kcgilegeu5/*/GET/dev\"}}}"
}
```

次にprodのステージ設定をまだ作成していないので、作成します。
ステージの作成はステージの設定からではなく、デプロイから行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/e7835737-4e4e-4801-0cce-c9f22b5ef0ed.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/4974f42e-7d68-b6a5-2e98-bbb4561ce3db.png)


デプロイが終わったら、ステージ変数を追加していきます。
クラスメソッドさんの記事にも記載されていますが、ステージ変数はあの[統合リクエスト]の画面で追加した変数名として、利用することができます。つまり、今回のケースでは__lambdaで作成したエイリアスを指定できる__ということになりますね。

>ステージ変数はステージごとに異なる値を設定でき、${stageVariables.xxxxx}で利用することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/f992b1e0-3fec-28a1-6072-978b39b03c72.png)

この状態でprodのエンドポイントに対して、curlでアクセスしてみると

```bash:prodエンドポイントへのアクセス
curl https://*********/prod/test01 -H 'x-api-key:******'
```

```bash:アクセス結果
"version1"
```

lambdaで設定しているエイリアスの通り、prodエイリアスで設定している"version1"の出力を返しました。
この時点ではまだ、devエイリアスには何も紐づけていないので、試しに新しいバージョンを作成して紐づけてみます。

ではlambda側で新しいバージョンを作成してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/fa9f27e3-5206-5018-8a7e-7ebf976c81e7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/fc150d4b-0ac7-92c5-dc16-8b9202f176ef.png)

新しいバージョンは"version2"を出力するという内容にします。
この状態でlambda側のエイリアスdevをこの新しく作成したバージョン2と紐づけておきます。

lambdaのエイリアスとバージョンの紐づけを変更する場合、[バージョンとエイリアスの切り替え]から[エイリアス:dev]を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/3881bca4-09cf-bf93-4bee-849dc8d1016f.png)

そこからエイリアスの設定画面に移って、画面下のほうに存在する[バージョン]のプルダウンメニューからエイリアス:devと紐づけるバージョンを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/ecd929b5-0c03-7958-efde-bca0716921fa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/3cc070e6-235d-f3ad-5e56-5c49ac7d7eff.png)

次に、実験として、この時点でlambda側の```$LATEST```の内容を"version3"に変えてみます。
この時点ではまだ、lambdaのdevとAPIゲートウェイのdevステージは紐づいていないので、仮に```$LATEST```を変更したらAPIゲートウェイのエンドポイントをたたいた出力結果は"version3"が返ってくるはずです。
※つまり、devはlambdaとは連携しない構成となっているはず。

では試しに、変えてみましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/ab207ff7-1ac6-188d-fcaa-de185dea90f5.png)

さぁ変えてみましたよ。これでdevのエンドポイントへアクセスしてみるとどうなるのでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/266fc820-1de9-f2e1-7d40-3437f25e49c8.png)

```bash:devエンドポイントへのアクセス
curl https://*********/dev/test01 -H 'x-api-key:******'
```

```bash:アクセス結果
"version3"
```

ちゃんと、"version3"が返ってきました！
ちなみにprodステージに反映させたデプロイの設定をdevステージにも同様に反映させることが可能です。
APIゲートウェイの[ステージ]でdevステージを選択し、[デプロイ履歴]を選択すると、prodステージで反映したデプロイの履歴が残っているので、選んだ状態で[デプロイの変更]をクリックし、devステージへ適用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/827efd27-a434-29b7-e7ea-f100185bafc9.png)

↓のように✔の位置が変わればOKです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/cd0260f0-a7a8-6ce5-71d1-22ed4d681e78.png)

あとはprodと同様にステージ変数でdevと設定してあげれば、lambdaのdevエイリアスと紐づけることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/a48d8e06-ba3b-59e4-3372-e85ac89785fd.png)

この状態でアクセスすると結果は先ほど、lambdaでdevエイリアスに紐づけた"version2"の結果が返ってくるはずです。

```bash:devエンドポイントへのアクセス
curl https://*********/dev/test01 -H 'x-api-key:******'
```

```bash:アクセス結果
"version2"
```

最初、この記事を読んだときはややこしかったのですが、実際に触ってみると覚えることができました。
やっぱり、こういった技術は触れて覚えていくことが一番大事ですね。

明日もまた、別のlambdaの勉強記事をアップしたいと思います。