【Lambda】バージョン管理のススメ

マッシュルーム
2024-12-19
2024-12-19

皆さんはLambdaのバージョン管理やデプロイってどうしてますか?

Github?  CodeCommit?
いろいろありますよね。

実はLambdaにはバージョン機能とエイリアス機能というものがあって、それらを駆使すると良い感じに運用できちゃうんです!

当記事では、そんなバージョン管理の魅力や設定方法について触れていきます。

(縦スクロールバーのサイズで察してください、引き返すなら今だぞ!)

目次

最新のみを保持するケース

バージョン管理

エイリアスの追加

設定例(APIゲートウェイ)

動作確認!!

注意点



最新のみを保持するケース

私が携わったプロジェクトでは、常に最新版のLatestに上書きするといった運用を取っていました。

例えば、実行環境には「開発」「検証」「ステージング」「本番」といった4つの環境が存在し、それぞれには全く同じコードのLambdaを作成するといった運用です。

この運用を用いたいくつかのケースを紹介しましょう

▼ケース1 Lambda_Aに対してコードをデプロイする

1.開発環境内のLambda_Aにコードをデプロイ
2.問題が無ければ、検証環境内のLambda_Aにコードをデプロイ
3.問題が無ければ、ステージング環境内のLambda_Aにコードをデプロイ
4.問題が無ければ、本番環境内のLambda_Aにコードをデプロイ


▼ケース2 本番環境のLambda_Aにコードをデプロイしたが、問題発生

1.本番環境内のLambda_Aにコードをデプロイ
2.本番環境内のLambda_Aで問題が発覚、デプロイ前のコードを取得する
3.前のコードを本番環境内のLambda_Aに再デプロイ



これ、しんどくないですか?



全く同じコードを各環境にデプロイすることはLambda関数が少なければマシだけど、数が多ければデプロイミスが起こりやすい。

1. 開発環境内のLambda_Aにコードをデプロイ
2. 検証環境内のLambda_Aにコードをデプロイ
3. ...したつもりが、誤ってLambda_Bのコードをデプロイしてしまった

このように、ヒューマンエラーも起こりやすくなります。

ロールバックが必要なケース2に関しては、迅速な対応が必要となるも、前のコードを探して取得する...といった作業が必要となります。


これらは全て、Lambdaのバージョン管理機能を使用することによって改善できちゃうんです!




 

バージョン管理

ではでは、Lambdaのバージョン管理方法について記していきます。

最初にLambda関数を作成しましょう。
イメージ図はLambda関数をPython3.12で作成した直後です。
lambda_apigateway_1

現在のバージョン名をレスポンスするコードに修正しました。
lambda_apigateway_2
lambda_apigateway_3


では早速新しいコードをデプロイし、バージョンを2にアップデートしましょう。
Lambdaのバージョン操作は、"バージョン" タブ内にて展開されています。
lambda_apigateway_4

"新しいバージョンを発行" ボタンを押下すると、バージョン発行のポップアップ画面が表示されます。
lambda_apigateway_5

それらしい説明を入力し "発行" ボタンを押下すると、バージョンが作成されます。
lambda_apigateway_6

これでバージョン1が作成されました。

引き続き最新版のLambdaのコードを「バージョン2だよ」に変更し、実行してみます。
lambda_apigateway_7
lambda_apigateway_8

修正したメッセージがレスポンスされました。
次に、バージョン1のLambdaを実行します。
lambda_apigateway_9

期待通り、バージョンを作成した時点の内容がレスポンスされました。

同じ手順でバージョンを5つほど作成してみました。
説明はそれらしく書いていますが、すべて「バージョン○○だよ」がレスポンスされるだけです。
lambda_apigateway_10



 

エイリアスの追加

ここまでで、5つのバージョンが作成されました。
次は各環境を示すエイリアスを作成し、バージョンと紐付けていきます。

まずは開発環境を示す "DEV" エイリアスを作成していきます。
エイリアスタブ内の "エイリアスを作成" を押下します。
lambda_apigateway_11


名前には "DEV" と入力し、バージョンには "$LATEST" を選択します。
全て入力後、"保存" ボタンを押下します。
lambda_apigateway_12


DEVエイリアスが作成され、最新バージョンであるLatestと紐付きました。
lambda_apigateway_13


同じ手順で、「QA」「STG」「PRD」も作成していきます。
lambda_apigateway_14


それぞれの環境には、次の通りのバージョンを紐付けました。
・DEV:Latest
・QA  :バージョン5
・STG:バージョン5
・PRD:バージョン4
lambda_apigateway_15

これで各環境にはどのバージョンが紐付いているのか、視覚的に分かりやすくなりました!

 

設定例(APIゲートウェイ)

バージョンとエイリアスを使ったコード管理はできるようになりましたが、
じゃあどうやってQAやSTGのLambdaをコールするのか

普通にコールしてしまうと、Latestが呼ばれてしまいます。

今回はLambda ⇔ APIゲートウェイの組み合わせで、
APIとして各エイリアスに紐づくLambdaをコールできるように設定していきます。

ではでは、早速APIゲートウェイを作っていきましょう
イメージ図はRESR-APIとして空のAPIを作成した直後です。

まずは呼び出しURLを定義します。"リソース作成" ボタンを押下します。
lambda_apigateway_16


リソース名は「test」として作成します。
lambda_apigateway_17


これで、「https://XXXXXXX/test」のURLが定義できました。
次に、上記URLにHTTPメソッドを定義します。"メソッドを作成" ボタンを押下します。
lambda_apigateway_18


「バージョン○○だよ」という文字列をレスポンスするLambdaが対象となるので、"GET" で定義します。

◎メソッドタイプ
  ➡ GET

◎Lambda関数
  ➡ arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:Test

lambda_apigateway_19

<< 重要ポイント! >>

Lambda関数には作成した「Test」関数を指定しましたが、関数名の最後に「:${stageVariables.aliasName}」を追記します。
すると、次のようなコマンドが表示されます。
lambda_apigateway_20

aws lambda add-permission \
--function-name "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:Test:${stageVariables.aliasName}" \
--source-arn "arn:aws:execute-api:ap-northeast-1:XXXXXXXXXXX:XXXXXXX/*/GET/test" \
--principal apigateway.amazonaws.com \
--statement-id XXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
--action lambda:InvokeFunction


これは、Lambda関数 ⇔ APIゲートウェイ間でのエイリアスを使用した呼び出しを可能とする許可設定コマンドです。
今回は「DEV」「QA」「STG」「PRD」の4環境があるので、2行目の「${stageVariables.aliasName}」の部分を各環境名に置換し、計4回コマンドを実行する必要があります。


コマンドはCloudShellから実行します。
lambda_apigateway_21

2行目の「${stageVariables.aliasName}」の部分を「DEV」に置換し、コマンドを実行します。

aws lambda add-permission \
--function-name "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:Test:DEV" \
--source-arn "arn:aws:execute-api:ap-northeast-1:XXXXXXXXXXX:XXXXXXX/*/GET/test" \
--principal apigateway.amazonaws.com \
--statement-id XXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
--action lambda:InvokeFunction


成功すると、以下のようなメッセージがレスポンスされます。
同じように、「QA」「STG」「PRD」のコマンドも実行します。
lambda_apigateway_22

CloudShellを閉じ、"メソッドを作成" ボタンを押下します。
lambda_apigateway_23


次に、各環境分のAPIステージを作成します。
"APIをデプロイ" ボタンを押下します。
lambda_apigateway_24

◎ステージ名
 ➡ 新しいステージ

◎ステージ名
 ➡ DEV

上記を入力して、"デプロイ" ボタンを押下します。
※同じように、「QA」「STG」「PRD」のステージも作成します。
lambda_apigateway_25

これで4つのステージが作成されました。
最後に、ステージ変数を設定します。ステージ変数タブ内の "編集" を押下します。
lambda_apigateway_26

◎名前
 ➡ aliasName

◎値
 ➡ DEV

上記を入力して、"保存" ボタンを押下します。
※同じように、「QA」「STG」「PRD」のステージ変数も作成します。
lambda_apigateway_27

各ステージに1つ、ステージ変数が設定できました。
これで準備完了です。
lambda_apigateway_30

 

 

動作確認!!

テスト前に、状況を整理します。

・DEV:Latest
・QA  :バージョン5
・STG:バージョン5
・PRD:バージョン4
lambda_apigateway_28

・新しくバージョン5がリリースされた

・QA環境での検証はOKで、現在はSTG環境にて検証中
・STG環境での検証完了後、PRD環境にバージョン5をデプロイする...

といったストーリーでいきます。


まずはSTG環境のLambdaのAPIエンドポイントを確認します。
URLはステージから確認できます。
lambda_apigateway_29


ではでは、STG環境のLambdaをコールします。
STGはバージョン5と紐付いています。

(今回APIコールには、Chrome拡張機能の「Talend API Tester」を使用しました)
lambda_apigateway_31

期待通り、「バージョン5だよ」が返ってきました!

続いて、PRD環境のLambdaをコールします。
PRDはバージョン4と紐付いています。
lambda_apigateway_32

こちらも期待通り、「バージョン4だよ」が返ってきました!

STG環境での動作確認が完了し、いよいよPRD環境にもバージョン5をデプロイします。
操作自体はとっても簡単で、PRDエイリアスに紐付いているバージョンを張り替えるだけでデプロイが完了します。

Lambdaコンソール画面に戻り、エイリアスタブよりPRDを選択し、"編集" ボタンを押下します。
lambda_apigateway_33

バージョン「5」を選択し、保存します。
lambda_apigateway_34

これだけで、PRD環境にバージョン5がデプロイされました!  超簡単!
lambda_apigateway_35

ではでは、PRDのAPIをコールしてみましょう
lambda_apigateway_36

「バージョン5だよ」が返ってきました!  やったー!!

そして次はロールバック
やったーと思ったけど、なんかやっぱりダメっぽいので前のバージョンに戻します。

ロールバックもバージョンを張り替えるだけで完了します。
lambda_apigateway_37
lambda_apigateway_38

再度、PRDのAPIをコールしてみましょう
lambda_apigateway_39

「バージョン4だよ」が返ってきました!
ロールバックを決意 ~ ロールバック完了まで15秒くらい。カチカチっとクリックするだけ



 

注意点

バージョン管理はデプロイ/ロールバックが効率的にはなりますが、注意点もあります。
それは、「環境変数やLambdaレイヤーはバージョン作成時点の設定で固定される」という点です。

あとからの変更はできないので、よく考えてバージョンを作成する必要があります。
また、環境変数にはDB接続情報など、各環境毎に固有の値が登録されているケースもよくありますが、全環境を1つのLambda関数で共有する都合上、そういった環境変数の使用の仕方もできなくなります。

各プロジェクトに合ったコードの管理方法を選択するとよいでしょう。

長い記事となりましたが、ここまでご拝読いただきありがとうございました!!