皆さんはLambdaのバージョン管理やデプロイってどうしてますか?
Github? CodeCommit?
いろいろありますよね。
実はLambdaにはバージョン機能とエイリアス機能というものがあって、それらを駆使すると良い感じに運用できちゃうんです!
当記事では、そんなバージョン管理の魅力や設定方法について触れていきます。
(縦スクロールバーのサイズで察してください、引き返すなら今だぞ!)
目次
● バージョン管理
● エイリアスの追加
最新のみを保持するケース
私が携わったプロジェクトでは、常に最新版の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で作成した直後です。
現在のバージョン名をレスポンスするコードに修正しました。
では早速新しいコードをデプロイし、バージョンを2にアップデートしましょう。
Lambdaのバージョン操作は、"バージョン" タブ内にて展開されています。
"新しいバージョンを発行" ボタンを押下すると、バージョン発行のポップアップ画面が表示されます。
それらしい説明を入力し "発行" ボタンを押下すると、バージョンが作成されます。
これでバージョン1が作成されました。
引き続き最新版のLambdaのコードを「バージョン2だよ」に変更し、実行してみます。
修正したメッセージがレスポンスされました。
次に、バージョン1のLambdaを実行します。
期待通り、バージョンを作成した時点の内容がレスポンスされました。
同じ手順でバージョンを5つほど作成してみました。
説明はそれらしく書いていますが、すべて「バージョン○○だよ」がレスポンスされるだけです。
エイリアスの追加
ここまでで、5つのバージョンが作成されました。
次は各環境を示すエイリアスを作成し、バージョンと紐付けていきます。
まずは開発環境を示す "DEV" エイリアスを作成していきます。
エイリアスタブ内の "エイリアスを作成" を押下します。
名前には "DEV" と入力し、バージョンには "$LATEST" を選択します。
全て入力後、"保存" ボタンを押下します。
DEVエイリアスが作成され、最新バージョンであるLatestと紐付きました。
同じ手順で、「QA」「STG」「PRD」も作成していきます。
それぞれの環境には、次の通りのバージョンを紐付けました。
・DEV:Latest
・QA :バージョン5
・STG:バージョン5
・PRD:バージョン4
これで各環境にはどのバージョンが紐付いているのか、視覚的に分かりやすくなりました!
設定例(APIゲートウェイ)
バージョンとエイリアスを使ったコード管理はできるようになりましたが、
じゃあどうやってQAやSTGのLambdaをコールするのか
普通にコールしてしまうと、Latestが呼ばれてしまいます。
今回はLambda ⇔ APIゲートウェイの組み合わせで、
APIとして各エイリアスに紐づくLambdaをコールできるように設定していきます。
ではでは、早速APIゲートウェイを作っていきましょう
イメージ図はRESR-APIとして空のAPIを作成した直後です。
まずは呼び出しURLを定義します。"リソース作成" ボタンを押下します。
リソース名は「test」として作成します。
これで、「https://XXXXXXX/test」のURLが定義できました。
次に、上記URLにHTTPメソッドを定義します。"メソッドを作成" ボタンを押下します。
「バージョン○○だよ」という文字列をレスポンスするLambdaが対象となるので、"GET" で定義します。
◎メソッドタイプ
➡ GET
◎Lambda関数
➡ arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:Test
<< 重要ポイント! >>
Lambda関数には作成した「Test」関数を指定しましたが、関数名の最後に「:${stageVariables.aliasName}」を追記します。
すると、次のようなコマンドが表示されます。
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から実行します。
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」のコマンドも実行します。
CloudShellを閉じ、"メソッドを作成" ボタンを押下します。
次に、各環境分のAPIステージを作成します。
"APIをデプロイ" ボタンを押下します。
◎ステージ名
➡ 新しいステージ
◎ステージ名
➡ DEV
上記を入力して、"デプロイ" ボタンを押下します。
※同じように、「QA」「STG」「PRD」のステージも作成します。
これで4つのステージが作成されました。
最後に、ステージ変数を設定します。ステージ変数タブ内の "編集" を押下します。
◎名前
➡ aliasName
◎値
➡ DEV
上記を入力して、"保存" ボタンを押下します。
※同じように、「QA」「STG」「PRD」のステージ変数も作成します。
各ステージに1つ、ステージ変数が設定できました。
これで準備完了です。
動作確認!!
テスト前に、状況を整理します。
・DEV:Latest
・QA :バージョン5
・STG:バージョン5
・PRD:バージョン4
・新しくバージョン5がリリースされた
・QA環境での検証はOKで、現在はSTG環境にて検証中
・STG環境での検証完了後、PRD環境にバージョン5をデプロイする...
といったストーリーでいきます。
まずはSTG環境のLambdaのAPIエンドポイントを確認します。
URLはステージから確認できます。
ではでは、STG環境のLambdaをコールします。
STGはバージョン5と紐付いています。
(今回APIコールには、Chrome拡張機能の「Talend API Tester」を使用しました)
期待通り、「バージョン5だよ」が返ってきました!
続いて、PRD環境のLambdaをコールします。
PRDはバージョン4と紐付いています。
こちらも期待通り、「バージョン4だよ」が返ってきました!
STG環境での動作確認が完了し、いよいよPRD環境にもバージョン5をデプロイします。
操作自体はとっても簡単で、PRDエイリアスに紐付いているバージョンを張り替えるだけでデプロイが完了します。
Lambdaコンソール画面に戻り、エイリアスタブよりPRDを選択し、"編集" ボタンを押下します。
バージョン「5」を選択し、保存します。
これだけで、PRD環境にバージョン5がデプロイされました! 超簡単!
ではでは、PRDのAPIをコールしてみましょう
「バージョン5だよ」が返ってきました! やったー!!
そして次はロールバック
やったーと思ったけど、なんかやっぱりダメっぽいので前のバージョンに戻します。
ロールバックもバージョンを張り替えるだけで完了します。
再度、PRDのAPIをコールしてみましょう
「バージョン4だよ」が返ってきました!
ロールバックを決意 ~ ロールバック完了まで15秒くらい。カチカチっとクリックするだけ
注意点
バージョン管理はデプロイ/ロールバックが効率的にはなりますが、注意点もあります。
それは、「環境変数やLambdaレイヤーはバージョン作成時点の設定で固定される」という点です。
あとからの変更はできないので、よく考えてバージョンを作成する必要があります。
また、環境変数にはDB接続情報など、各環境毎に固有の値が登録されているケースもよくありますが、全環境を1つのLambda関数で共有する都合上、そういった環境変数の使用の仕方もできなくなります。
各プロジェクトに合ったコードの管理方法を選択するとよいでしょう。
長い記事となりましたが、ここまでご拝読いただきありがとうございました!!