目次Category
AWS Lambdaを利用して開発していると、 「開発中のコードを変更したら、本番環境にも反映されてしまうのでは?」 と気になることがあります。
そのようなときに活用できるのが、 AWS Lambdaのバージョニング機能です。
Lambdaでは、現在編集中のコードを表す
$LATESTとは別に、
その時点のコードをVersionとして固定できます。
この記事では、 Amazon API Gatewayのdev / prdステージと AWS Lambdaのバージョニングを組み合わせ、 開発環境と本番環境で異なるLambdaコードを実行する方法を解説します。
この記事でできること
- Lambdaの
$LATESTとVersionの違いを理解する - LambdaのコードをVersionとして固定する
- API Gatewayにdev / prdステージを作成する
- devから
$LATEST、prdから固定Versionを呼び出す - 開発中の変更が本番環境へ影響しないことを確認する
この記事の対象者
- AWSを学び始めた方
- Lambdaのバージョニングを初めて利用する方
- API GatewayとLambdaを組み合わせて利用したい方
- 開発環境と本番環境を分ける仕組みを学びたい方
Lambdaのバージョニングとは?
AWS Lambdaでは、現在編集中の最新コードを
$LATESTとして管理しています。
コードを変更して「Deploy」を行うと、
$LATESTの内容が更新されます。
↓
Deploy
↓
$LATESTが更新
一方、Lambdaでは$LATESTの現在の状態を
Version 1、Version 2……のように固定できます。
発行したVersionは、その時点のコードを固定したものとして扱われるため、
その後$LATESTを変更しても、
すでに発行したVersionの内容は変わりません。
ポイント
$LATESTは開発中の最新コード、
固定Versionは動作確認済みのコードを保存しておく用途として利用できます。
API Gatewayのステージとは?
Amazon API Gatewayでは、 同じAPIに対して複数のステージを作成できます。
今回は、以下の2つのステージを作成します。
| ステージ | 役割 |
|---|---|
| dev | 開発環境。Lambdaの$LATESTを呼び出す |
| prd | 本番環境。Lambdaの固定Versionを呼び出す |
今回構築する構成
今回は、API Gatewayのステージごとに 呼び出すLambdaを切り替えます。
↓
API Gateway / GET /hello
↓
dev → Lambda $LATEST(開発用)
prd → Lambda Version 1(本番用)
この構成にすることで、
$LATESTのコードを変更しても、
prdが固定Versionを参照している限り、
本番環境のコードは変更されません。
使用するAWSサービス
| サービス | 役割 |
|---|---|
| AWS Lambda | 開発用コードと本番用の固定Versionを管理する |
| Amazon API Gateway | dev / prdステージを作成し、呼び出すLambdaを切り替える |
| AWS CloudShell | API GatewayからLambdaを実行する権限を設定する |
1. Lambdaの本番用Versionを作成する
はじめにLambda関数を作成し、 本番用として使用するコードをVersionとして固定します。
手順1:Lambda関数を作成する
- AWSマネジメントコンソールで「Lambda」を検索します。
- 「関数の作成」を選択します。
- 「一から作成」を選択します。
- 関数名を入力します。
- ランタイムでPython 3.xを選択します。
- 「関数の作成」を選択します。
設定例
関数名:ojt-lambda-version-[名前]-01
ランタイム:Python 3.x
アーキテクチャ:x86_64
手順2:本番用コードを作成する
作成したLambda関数のコードを、 以下の内容へ変更します。
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps({
"message": "Production Version 1",
"version": "1"
})
}
入力後、「Deploy」を選択します。
手順3:本番用コードをテストする
Versionを発行する前に、 現在のコードが正常に動作することを確認します。
- Lambda画面の「Test」を選択します。
- 初回は新しいテストイベントを作成します。
- イベント名に
test-lambdaと入力します。 - イベントJSONは
{}のまま保存します。 - 再度「Test」を選択します。
実行結果で、以下の内容を確認します。
確認するポイント
Status: SucceededになっているProduction Version 1が返っているVersion: $LATESTと表示されている
この時点ではまだVersionを発行していないため、
$LATESTが実行されています。
手順4:本番用Versionを発行する
コードが正常に動作することを確認できたら、 その時点のコードを本番用として固定します。
- Lambda関数画面の「アクション」を選択します。
- 「新しいバージョンを発行」を選択します。
- 必要に応じて説明を入力します。
- 「発行」を選択します。
↓
新しいVersionを発行
↓
Version 1(本番用)
Version番号について
初めてVersionを発行する場合は、基本的にVersion 1になります。 すでにVersionを発行したことがある場合は、 Version 2以降になることがあります。 その場合は、以降の設定を実際のVersion番号へ読み替えてください。
2. $LATESTを開発用コードに変更する
本番用のVersionを固定できたので、
次に$LATESTを開発用コードへ変更します。
Version 1の画面を開いている場合は、 Lambda関数名を選択して通常の関数画面へ戻ります。
以下のコードへ変更し、「Deploy」を選択します。
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps({
"message": "Development Latest",
"version": "latest"
})
}
Development Latest
↓
開発用
Version 1
Production Version 1
↓
本番用
ポイント
変更しているのは$LATESTのみです。
先ほど発行したVersion 1は固定されているため、
内容は変更されません。
3. API Gatewayを作成する
手順1:REST APIを作成する
- AWSマネジメントコンソールで「API Gateway」を検索します。
- 「APIを作成」を選択します。
- REST APIを選択します。
- 必要な項目を入力してAPIを作成します。
設定例
API名:ojt-api-version-[名前]-01
APIタイプ:新しいAPI
エンドポイントタイプ:リージョン
注意
API GatewayとLambdaは、同じAWSリージョンに作成してください。
手順2:/helloリソースを作成する
作成したREST APIに、
/helloリソースを作成します。
| 項目 | 設定値 |
|---|---|
| プロキシのリソース | OFF |
| リソースパス | / |
| リソース名 | hello |
手順3:GETメソッドを作成する
作成した/helloリソースへ、
GETメソッドを追加します。
| 項目 | 設定値 |
|---|---|
| メソッドタイプ | GET |
| 統合タイプ | Lambda関数 |
| Lambdaプロキシ統合 | ON |
| Lambda関数 | ${stageVariables.lambdaTarget} |
今回はLambda関数名を直接指定せず、 ステージ変数を利用します。
↓
dev → Lambda関数名
prd → Lambda関数名:Version番号
ステージ変数とは?
ステージごとに異なる値を設定できる変数です。 今回は、devとprdで呼び出すLambdaを切り替えるために使用します。
4. dev / prdステージを作成する
手順1:devステージを作成する
APIをデプロイし、
新しいステージとしてdevを作成します。
作成後、ステージ変数に以下を設定します。
devのステージ変数
名前:lambdaTarget
値:ojt-lambda-version-[名前]-01
devではVersion番号を付けません。
Versionを指定しないことで、
$LATESTが呼び出されます。
手順2:prdステージを作成する
再度APIをデプロイし、
新しいステージとしてprdを作成します。
prdのステージ変数
名前:lambdaTarget
値:ojt-lambda-version-[名前]-01:1
末尾の:1は、
LambdaのVersion 1を指定しています。
| ステージ | lambdaTarget | 呼び出し先 |
|---|---|---|
| dev | Lambda関数名 | $LATEST |
| prd | Lambda関数名:1 | Version 1 |
5. API GatewayからLambdaへの実行権限を設定する
ステージ変数を使用してLambdaを指定しているため、 API GatewayからLambdaを実行できるように権限を追加します。
AWSマネジメントコンソールから CloudShellを開きます。
手順1:dev用の実行権限を追加する
aws lambda add-permission \
--function-name ojt-lambda-version-[名前]-01 \
--statement-id apigateway-dev \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--region ap-northeast-1
手順2:prd用の実行権限を追加する
aws lambda add-permission \
--function-name ojt-lambda-version-[名前]-01 \
--qualifier 1 \
--statement-id apigateway-prd \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--region ap-northeast-1
リージョンについて
上記は東京リージョン
ap-northeast-1の例です。
大阪リージョンを利用している場合は、
ap-northeast-3へ変更します。
–qualifier 1とは?
prdから実行を許可するLambdaのVersionを指定しています。
Version 2を使用する場合は、
--qualifier 2のように変更します。
6. dev / prdの動作を確認する
手順1:devへアクセスする
API Gatewayのdevステージに表示されているURLの末尾へ
/helloを付けてアクセスします。
https://API-ID.execute-api.ap-northeast-1.amazonaws.com/dev/hello
以下のように表示されれば成功です。
{
"message": "Development Latest",
"version": "latest"
}
手順2:prdへアクセスする
https://API-ID.execute-api.ap-northeast-1.amazonaws.com/prd/hello
以下のように表示されれば成功です。
{
"message": "Production Version 1",
"version": "1"
}
確認結果
devでは$LATESTの「Development Latest」、
prdでは固定Versionの「Production Version 1」が返りました。
同じLambda関数でも、API Gatewayのステージによって
異なるVersionを呼び分けられていることを確認できました。
7. $LATESTを変更しても本番環境に影響しないことを確認する
最後に、
$LATESTを変更した際の
dev / prdの動作を確認します。
Lambdaの$LATESTを以下のコードへ変更します。
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps({
"message": "Development Latest Updated",
"version": "latest-v2"
})
}
変更後、「Deploy」を選択します。
devを再確認する
{
"message": "Development Latest Updated",
"version": "latest-v2"
}
devは$LATESTを参照しているため、
変更した内容が反映されます。
prdを再確認する
{
"message": "Production Version 1",
"version": "1"
}
prdはVersion 1を参照しているため、
$LATESTを変更してもレスポンスは変わりません。
├─ $LATEST
│ ↑
│ dev
│
└─ Version 1
↑
prd
確認結果
$LATESTを変更するとdevには新しい内容が反映されましたが、
prdではVersion 1の内容がそのまま表示されました。
これにより、開発中の変更が本番環境へ影響しないことを確認できました。
8. 実際の運用ではどのように使う?
今回の構成を実際の開発・本番運用に置き換えると、 以下のような流れになります。
↓
② dev環境で動作確認
↓
③ 問題がなければ新しいVersionを発行
↓
④ prdの参照先を新Versionへ変更
↓
⑤ 本番環境へ反映
新しいVersionを本番へ反映する場合
例えばVersion 1を本番で利用しており、 新しいコードを本番へ反映する場合は、 動作確認後にVersion 2を発行します。
その後、prdのステージ変数を 以下のように変更します。
ojt-lambda-version-[名前]-01:1↓
ojt-lambda-version-[名前]-01:2
問題が発生した場合
Version 2を本番へ反映したあとに問題が見つかった場合は、 prdの参照先を以前のVersion 1へ戻すことができます。
↓
問題発生
↓
Version 1へ戻す
↓
以前の状態へ復旧
このように以前の安定したVersionへ戻すことを ロールバックといいます。
9. よくあるエラー・確認ポイント
Versionの画面でDeployが押せない
発行済みのVersionは読み取り専用のため、 コードを編集できません。
Lambda関数名を選択して
$LATESTの画面へ戻ってから編集します。
Version 1ではなくVersion 2以降になった
問題ありません。
prdのステージ変数やCloudShellの
--qualifierを、
実際に発行されたVersion番号へ変更します。
APIへアクセスするとエラーになる
- URLの末尾に
/helloが付いているか確認する - LambdaとAPI Gatewayが同じリージョンか確認する
- dev / prdのステージ変数を確認する
- Lambdaの実行権限が追加されているか確認する
10. ハンズオン終了後のリソース削除
ハンズオン終了後は、 今回作成したリソースを削除します。
↓
② Lambda
API Gatewayを削除する
API GatewayのAPI一覧から、
今回作成した
ojt-api-version-[名前]-01
を削除します。
API自体を削除すると、
/hello、
GETメソッド、
dev / prdステージ、
ステージ変数もまとめて削除されます。
Lambdaを削除する
Lambdaの関数一覧から、
ojt-lambda-version-[名前]-01
を選択して削除します。
Lambda関数自体を削除すれば、
$LATESTや公開済みVersionを
個別に削除する必要はありません。
ポイント
ハンズオンで作成した不要なリソースは、 動作確認が終わったら削除しておきましょう。
まとめ
今回確認したこと
$LATESTと固定Versionの違い- LambdaのコードをVersionとして固定する方法
- API Gatewayにdev / prdステージを作成する方法
- ステージ変数を使って呼び出すLambdaを切り替える方法
$LATESTを変更してもprdに影響しないこと
API GatewayのステージとLambdaのバージョニングを組み合わせることで、 開発環境と本番環境で異なるLambdaコードを実行できました。
今回の構成では、
devから$LATEST、
prdから固定Versionを呼び出すことで、
開発中のコード変更が本番環境へ直接影響しないことを確認できました。
また、新しいVersionへ切り替えることで本番リリースを行ったり、 問題が発生した際に以前のVersionへ戻したりできるため、 Lambdaを利用したアプリケーションを運用する際に役立つ仕組みです。
まずは今回のようにdev / prdで異なるVersionを呼び分け、 LambdaのバージョニングとAPI Gatewayのステージの仕組みに慣れてみてください。
同じカテゴリーの記事
同じカテゴリの記事を読む