こんにちは。 エキサイト株式会社の三浦です。
ECSにAWS CLIを使ってデプロイするとき、皆さんはデプロイの完了をどうやって検知しますか?
今回は、デプロイ完了検知に aws ecs wait services-stable
を使用したときの問題点について説明します。
AWS CLIとECSへのデプロイ
ECSへのデプロイ方法はいくつかありますが、その中の一つにAWS CLIを使用するというものがあります。
aws ecs update-service \ --cluster クラスタ名 \ --service サービス名 \ --task-definition タスク定義のARN
これだけでECSへのデプロイが実現できるので、AWS CLIのインストールやAWS環境への認証さえ行っていれば、非常にお手軽なデプロイ方法になります。
ただし、このコマンドはデプロイは実行してくれるものの、デプロイの完了を待たずにコマンド実行を終了してしまうため、実際にデプロイが完了したかを待つためには別の方法を取る必要があります。
そのために、 aws ecs wait services-stable
というコマンドが用意されています。
aws ecs wait services-stable \ --cluster クラスタ名 \ --service サービス名
このコマンドは、実行すると「ECSサービスが安定化」するまで待ち続けてくれるため、 aws ecs update-service
実行後にこのコマンドを実行することで、デプロイを待ってくれます。
これで一見問題ないように見えますが、実は「ECSサービスが安定化」するという定義が少し曲者で、そのせいで aws ecs wait services-stable
だけではデプロイを待つのに不十分な場合があります。
ALBを使用したECSへのデプロイでの問題点
aws ecs wait services-stable
における「ECSサービスの安定化」とは、以下のような定義になります。
Wait until JMESPath query length(services[?!(length(deployments) == 1 && runningCount == desiredCount)]) == 0 returns True
上記の通り、実はこのコマンドはALBのヘルスチェック等は特に見ておらず、あくまでECS上で deployments
の数が1つだけで、 runnningCount
と desiredCount
の数が同じ、というところしか見ていません。
そのため、例えばALBと接続したECSで「ヘルスチェックの猶予期間」等を長めに指定していたために、ALBのヘルスチェックが通ったかはまだ確定していないものの、ECSの上記のパラメータだけは問題ない数値に落ち着いてしまった場合、 aws ecs wait services-stable
は「成功した」として終了してしまうのです。
そういった意味では、残念ながらALBを使用したECSへのデプロイでは、 aws ecs wait services-stable
による待機だけでは不十分ということになります。
なにか別の方法で、ALBのヘルスチェックが通ったことを検知する必要があるでしょう。
最後に
aws ecs wait services-stable
のこの仕様は、特に不具合というわけではないと思われます。
というのも、ECSは必ずしもALBを使う必要がないサービスであり、ALBを使わないのであれば現在の挙動で十分だからです。
必要に応じて、必要な検知方法を検討・使用して行きましょう。