☕️

ecspresso advent calendar 2020 day 6 - rollback

2020/12/06に公開

Amazon ECS のデプロイツールである ecspresso の利用法をまとめていく ecspresso Advent calendar 6日目です。

ロールバックを行う

デプロイした結果に問題があった場合、ecspresso でサービスのロールバックを行う方法を説明します。

ここで説明する方法は、ECSサービスのデプロイ方法がローリングデプロイの場合にのみ適用できます。CodeDeploy による Blue/Green デプロイを使用する場合は、CodeDeploy の機能でロールバックを行ってください。

CodeDeploy との連携については17日目を参照してください。

ECS タスク自体が正常に起動しない場合

2020-11-30 にアナウンスされた deployment circuit breaker 機能をサービスに対して有効にすることで、タスクが正常に起動しない個数が閾値を超えた場合に、自動的にひとつ前のタスク定義を使用している状態に戻すことができます。

Announcing Amazon ECS deployment circuit breaker

ecspresso では v1.1.3 以降で対応しています。

サービス定義にある deploymentConfiguration.deploymentCircuitBreaker の enable, rollback 属性を true に設定することで、deployment circuit breaker が有効になります。

{
  "deploymentConfiguration": {
    "deploymentCircuitBreaker": {
      "enable": true,
      "rollback": true
    },
    "maximumPercent": 200,
    "minimumHealthyPercent": 100
  },
  // ...
}

タスクは正常に起動したが、アプリケーションの動作に問題がある場合

タスクは正常に起動したもののアプリケーションの動作に問題が発生したいので戻したい場合には、ecspresso rollback コマンドを使用します。

$ ecspresso rollback --help
usage: ecspresso rollback [<flags>]

rollback service

Flags:
  --help                        Show context-sensitive help (also try --help-long and
                                --help-man).
  --config=CONFIG               config file
  --debug                       enable debug log
  --dry-run                     dry-run
  --deregister-task-definition  deregister rolled back task definition
  --no-wait                     exit ecspresso immediately after just rollbacked without
                                waiting for service stable

rollback コマンドを実行すると、以下の処理が行われます。

  1. 現在サービスに設定されているタスク定義の「ひとつ前」のリビジョンを見つける
  2. ひとつ前のリビジョンのタスク定義をサービスに設定する

タスク定義 my-service:4 がサービスに設定されていて、ECS に登録されているタスク定義が次のようになっている場合にロールバックを行うと、my-service:2 にサービスを更新します。

  • my-service:4
  • my-service:2
  • my-service:1

rollback コマンドのオプション

--deregister-task-definition

ロールバックを行ったタスク定義を登録解除 (deregister) します。デフォルトでは登録解除を行いません。

  • my-service:4 (設定中)
  • my-service:2
  • my-service:1

タスク定義がこの状態からリビジョン 4 をロールバックした場合、ECS に登録されているタスク定義はそのまま残ります。

  • my-service:4 (ロールバック済)
  • my-service:2 (設定中)
  • my-service:1

この状態で次のデプロイを行うとリビジョン 5 が登録されます。そこでまたロールバックを行うと、5 のひとつ前のリビジョンは 4 なので(先ほどロールバックした)リビジョン 4 が設定されてしまいます。そもそもリビジョン 4 はなんらかの問題が発生したためにロールバックしたわけですから、これは望ましくない状態のことが多いでしょう。

  • my-service:5 (ロールバック済)
  • my-service:4 (設定中)
  • my-service:2
  • my-service:1

--deregister-task-definition を指定すると、ロールバックを行った後にタスク定義を登録解除します。リビジョン 4 はロールバック後に削除され、以下の状態になります。

  • my-service:4 (削除済)
  • my-service:2 (設定中)
  • my-service:1

この状態で次のデプロイを行ってリビジョン 5 を登録すると以下のようになり、ここでリビジョン 5 をロールバックしたとしてもリビジョン 4 に戻ることはありません。

  • my-service:5 (設定中)
  • my-service:2
  • my-service:1

ロールバック済みのタスク定義を残しておくと、デプロイとロールバックを複数回繰り返した場合に以前ロールバックした(つまり問題がある)タスク定義が意図せず使用されてしまう可能性があります。

特別な事情がない場合は --deregister-task-definition オプションを指定してロールバックを行うことをおすすめします。

--no-wait

deploy --no-wait と同様、タスク定義をロールバック後に完了を待たず、即終了します。


7日目は現在の ECS サービスの状態を表示する方法を説明します。

https://zenn.dev/fujiwara/articles/ecspresso-20201207

Discussion