[API Gateway + Lambda]ステージとエイリアスを使ってバージョン管理してみた

こんにちは、臼田です。

皆さん、Lambdaしていますか?

今回はAPI Gateway + Lambdaでprodやdevのエンドポイント毎に対応したバージョンのLambda関数を動かしてみたいと思います。

API Gateway + Lambdaのセットアップは下記ブログをご参照下さい。

ゼロから作りながら覚えるAPI Gateway環境構築

何がしたいか

APIを作成して運用していく中で、本番用のエンドポイントとは別で、開発用のエンドポイントを用意して、それぞれ別のバージョンのLambdaを実行したくなります。

API Gatewayには1つのAPIを複数のステージにデプロイし、エンドポイントを複数作成することができます。例えば下記のようになります。

  • https://xxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev
  • https://xxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod

Lambda関数も1つの関数で複数のバージョンを持つことができます。

また、バージョンと対応するエイリアスを設定することができます。

例としては、バージョンを1, 2のような形で作成していき、そのバージョンと紐づくdev, prodエイリアスを設定する事ができます。また、$LATESTというバージョンが常に最新の状態を指しているため、devエイリアスを$LATESTに当てることも多いです。

このAPI GatewayのステージとLambdaのエイリアスを紐付けて、以後のバージョン管理を楽にしたいと思います。

やってみた

文章だとわかりづらいので早速やってみます。API GatewayやLambda関数は構築してあるところから始めます。

Lambdaのバージョン・エイリアス設定

Lambda関数は作成済みの想定です。下記はversion 1をreturnするだけの関数です。

001_v1

Lambda関数は作成されただけの状態だとまだバージョンは作成されていない状態になります。バージョン情報は「限定条件」から確認できます。

002_v1

バージョンの作成は「アクション -> 新しいバージョンを発行」から行います。なお、バージョンの作成をすると作成されたバージョンは変更できないので気をつけましょう。($LATESTは引き続き変更可能です)

003_create_version

バージョンの説明を適当に設定して「発行」します。

004_v1

バージョン1が発行されました。パンくずからバージョン1を表示している事がわかったり、ARNもバージョンを含んだものに変更されていることがわかります。

005_v1

バージョンを作成した場合、コード部分がホワイトアウトして編集できなくなります。編集する場合には$LATESTに戻るか、パンくずから関数名をクリックして移動する必要があります。

011_v1

続いて、エイリアスを作成します。「アクション -> エイリアスの作成」へ移動します。

006_v1

devエイリアスを作成し、$LATESTと紐付けます。

007_v1

エイリアスが作成され、$LATESTに紐付いている事が確認できます。パンくずやARNもバージョンと同様に変わっています。

008_v1

もう一つprodエイリアスを同じように作成します。こちらはバージョン1に紐付けます。

009_v1

「エイリアス(限定条件の場所) -> 別名」でdev$LATESTprod1と紐付いていることが確認できます。

010_v1

現状ではバージョン1$LATESTが実質同じなので、$LATESTを編集します。$LATESTを選択して移動します。

012_v1

returnをveresion 2に変更して保存します。

013_v2

これでLambda側の準備は完了しました。

API Gatewayの設定

API Gatewayについては構築が完了し、devステージのみデプロイされている想定です。

devステージは特にエイリアスと紐付けてない状態のため、エンドポイントへリクエストすると$LATESTの結果が返ってきます。

014_dev

015_dev

まずはLambdaのエイリアスと対応付ける設定を行います。Lambdaと関連付けているメソッドのページから「統合リクエスト」へ移動します。

017_v1

「Lambda関数」項目で鉛筆マークを押して編集します。関数名の後ろに:${stageVariables.alias}を付けて保存します。こちらはAPI Gatewayのステージ変数を参照する設定です。ステージ変数は後ほど説明します。

018_v1

保存時に「Lambda関数に権限を追加する」という項目とともに権限を追加するためのスクリプトが生成されます。ステージとエイリアスを紐付けるためには、現状CLIから手動で権限を追加する必要があります。こちらのコードを控えます。

019_v1

AWS CLIにて控えたコードを実行します。ただし、コードの中にある${stageVariables.alias}は実際のエイリアスの値を入れる必要があります。そのため、devprodで2回実行します。

$ aws lambda add-permission --function-name arn:aws:lambda:ap-northeast-1:000000000000:function:test-hello:dev --source-arn 'arn:aws:execute-api:ap-northeast-1:000000000000:xxxxxxxxxx/*/GET/' --principal apigateway.amazonaws.com --statement-id 00000000-000000000-000000000000000 --action lambda:InvokeFunction
{
    "Statement": "{\"Sid\":\"00000000-000000000-000000000000000\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:000000000000:function:test-hello:dev\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:000000000000:xxxxxxxxxx/*/GET/\"}}}"
}

$ aws lambda add-permission --function-name arn:aws:lambda:ap-northeast-1:000000000000:function:test-hello:prod --source-arn 'arn:aws:execute-api:ap-northeast-1:000000000000:xxxxxxxxxx/*/GET/' --principal apigateway.amazonaws.com --statement-id 00000000-000000000-000000000000000 --action lambda:InvokeFunction
{
    "Statement": "{\"Sid\":\"00000000-000000000-000000000000000\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:000000000000:function:test-hello:prod\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:000000000000:xxxxxxxxxx/*/GET/\"}}}"
}

Windowsのコマンドプロンプトでawscliを利用している場合には、--source-arn'が適切に処理されないので、"に置き換えて実行して下さい。

それではprodステージを作成します。

020_prod

デプロイしたら、ステージ変数を設定します。ステージ変数はステージごとに異なる値を設定でき、${stageVariables.xxxxx}で利用することができます。ここに、先程のLambda関数のエイリアスに入れたい値を設定します。

「ステージ変数の追加」から追加します。

021_prod

名前にalias、値にprodを入れてチェックを押します。

022_prod

この状態でURLの呼び出しからprodのエンドポイントをリクエストすると、version 1が返ってきます。Lambdaのprodエイリアスと紐付いているバージョン1が返していることがわかります。

023_prod

024_prod

さて、この状態ではdevではエイリアスと紐付ける設定がされていません。試しに新しいバージョンを作成してLambda関数のdevエイリアスを、$LATEST以外にしてみます。

$LATESTから「新しいバージョンを発行」してバージョン2を作成します。

025_v2

バージョン選択から「別名 -> dev」を選択します。

026_dev

バージョンを$LATESTから2に変更して保存します。

027_v2

$LATESTに移動して、returnをversion 3に変更して保存します。

028_dev

devのエンドポイントにリクエストすると、$LATESTの結果であるversion 3が返ってきて、Lambda側のエイリアスの設定が反映されていないことが確認できます。

029_v3

さて、devステージの更新ですが、新たにAPI Gatewayのリソース画面からデプロイしてもいいですが、prodでデプロイしたバージョンと同じものを選択できます。

devステージへ移動して「デプロイ履歴」から、これまでのデプロイが一覧で表示されますので、新しいバージョンを選んで「デプロイの変更」を押します。

030_dev

これでリクエスト先のLambda関数にエイリアスを入れる設定が反映されました。あとはステージ変数を設定します。

031_dev

この状態でdevへリクエストすると、version 2が返ってきてエイリアスが反映されていることが確認できました。

015_dev

おわりに

これでLambda側でバージョンとエイリアスの設定を変えるだけで、API自体の動作を変更することができるようになりました。

それでは快適な開発ライフを!