はじめに
LambdaのCanaryリリースは非常に便利。自動でトラフィックコントロールをして様子を見ることができる。
しかし、クラウドネイティブなリリースの完成は、万が一の状況を検知した場合は自動でロールバックすることだ。
今回は、過去に作ったSAMテンプレートに自動ロールバックを組み込んで実際の動作を確認する。
前提条件
- SAMテンプレートでCanaryリリースの設定を書いたことがあり、ある程度内容を理解している。特に、
AutoPublishAlias
とDeploymentPreference
の概要と、LambdaPermission
を設定しなければいけない理由が分かっているのが望ましい ⇒ 過去の記事でも紹介してるよ! - CloudWatchアラームをなんとなく分かっている
SAMテンプレートを書く前に
ロールバックの設定は、SAMテンプレートのAWS::Serverless::Function
リソース内のDeploymentPreference
のプロパティで設定する。これは標準のCloudFormationにはないSAM独自機能なので、マニュアルには目を通しておく。
このドキュメントのAlarms
の説明には
デプロイによって発生したエラーによってトリガーされる CloudWatch アラームのリスト。
と書かれていて「ごめんちょっとよく分からない」な感じではあるが、要はここで設定したCloudWatchアラームに引っかかるとトリガが引かれてロールバックが走る、ということだった。
なので、ここに指定するCloudWatchアラームを定義してあげればよい。指定するのはARNではなくて名前なので、TerraformとSAMを併用している場合でも、それほど困らずに使えるだろう。
CloudWatchAlarmの定義
デプロイ中に発生する問題を予見するようなアラームなんて千差万別なので「これ」という答えはないが、今回はサンプルとして、「APIGatewayの特定APIの特定ステージで、5XXErrorの合計値が60秒以内に2回以上発生したら挙がるアラーム」を設定する。
あっさり書いたようだが、この辺のプロパティの説明は公式ドキュメントの内容が破滅的に分かりにくいので、ほぼ手探りなのであった。NamespaceとDimensionsについては、API Gateway側のドキュメントに書かれていたので拾えた。Namespaceに設定可能な他のサービスについても、ここでまとめられているので、今後の参考に使えるのではないか。
なお、Dimensionsではリソースとメソッドまで指定できるが、それを拾うメトリクスはカスタムメトリクスの作成が必要そうなので今回は割愛する。実際には、デプロイするアプリケーションの影響範囲に応じて監視範囲を絞るべきだろう。
# ------------------------------------------------------------#
# Cloud Watch Alarm
# ------------------------------------------------------------#
GoApigwTestAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: [好きなアラーム名]
AlarmDescription: [適当な説明文]
Namespace: AWS/ApiGateway
Dimensions:
- Name: ApiName
Value: [APIGatewayのAPI名]
- Name: Stage
Value: Prod
MetricName: 5XXError
Statistic: Sum
Period: 60
ComparisonOperator: GreaterThanThreshold
Threshold: 1
EvaluationPeriods: 1
実際に試してみる
さて、上記のSAMテンプレートをリリースしたとしても、トランザクションを5XXエラーにできなければ意味がない。プロダクトのソースコードに
if id == "99999" {
statusCode = 500
}
な感じでテキトーに仕込んで、curlでid=99999を流し込もう。DeploymentPreference
のType
の内容次第ではなかなかエラーにならないが、「1分以内に2回5XXエラー」という設定なのでテキトーに叩いていればそのうちにロールバックが発動する。
ロールバックが発動すると、
こんな感じでトラフィックがオリジナル側にしか流れなくなり、ロールバックが完了する。