概要
- SAM などで Lambda Function 群を一斉にデプロイするケースの場合、 State Machine から Invoke する LambdaFunction のバージョンは明示的に指定したほうが良い
という話です。
実現したい要件
Step Function の呼び出し先の一群の Lambda Functions 達を一斉にデプロイする場合、デプロイの前後で有効になっているバージョンを厳密に切り替えたい。
前提
以下のようなアーキテクチャの場合を前提にしてます:
- Step Functions で一群の Lambda Function 達をオーケストレーションしている
- SAMなどを使って Step Functions の Node (Lambda Function) を同時にデプロイする
Lambda Function をバージョン指定せずに Invoke する場合
以下のいずれかに該当する場合です:
- デプロイ時に Lambda Function のバージョンがインクリメントされない
- State Machine でバージョン指定せずに invoke している
(以降では簡単のため、デプロイの前後でバージョンがインクリメントされない場合も旧いコードを Ver.1, 新しいコードをVer.2 と表記します。)
このようなアーキテクチャで sam deploy
を実行したとすると、
デプロイ中に State Machine が invoke された場合、個々のLambda Functionはどのバージョンが呼び出されるかわかりません。
したがって、Ver.1 のコードと Ver.2 のコードが混在する状況が考えられます。
これだとアプリケーションの振る舞いが不確定になってしまうので、デプロイ前後でイベント伝搬を停止する必要が生じてしまいます。
これはすなわちサービス停止を意味します。
解決策: Lambda Function のバージョン指定して Invoke する
呼び出すLambda Function のバージョンを明示的に指定すれば、新旧のコードが混在することがないので、アプリケーションの振る舞いは確定的になります。
したがってサービスを止めることなくデプロイができます。
具体的な設定方法
デプロイツールに AWS SAM を使っている場合、具体的な設定方法は以下です。
- SAM で Lambda Function の AutoPublishAlias パラメータを有効にする
- State machine 定義の Lambda Function の ARN をバージョンまで指定する
これを、
!GetAttr YourLambdaFunction.Arn
こうします。
Globals:
Function:
AutoPublishAlias: yourTag
!Ref YourLambdaFunction.Version
今後の課題
今後の課題として、以下があります:
- Blue-Green Deploy のように、直前までうまく動いていた環境にすぐに切り戻せるようにしたい
- Lambda Layer を利用している場合も適切に切り替えたい
1について、
これは Lambda の Alias を利用すれば実現できるかもしれません。
State Machine と Lambda Function を別々にデプロイする必要はありそうですが。
2について、
Lambda Layer を利用している場合、Step Function を invoke した時点では、どのバージョンの Lambda Layer が有効になるかコントロールできないため、別の方法で新旧の系切り替えが必要になります。
例えば、デプロイごとに StepFunction, Lambda Layer, Lambda Function といった一連のリソースを 毎回 Immutable に生成する ような方法が考えられます。
これらの課題については、良い方法が実現できたらまた別の機会に書こうと思います。