124. Elastic Beanstalkの5つのデプロイポリシーは『速さ・容量・安全』の交換である — all at onceからtraffic splittingまで
Elastic Beanstalkのデプロイポリシーは5つあるように見えて、実は「既存インスタンスをどう扱うか」という1本の軸の上に並んだ5つの点にすぎません。その軸を「箱の中身を入れ替えるか、箱ごと替えるか」で図に追っていきます。
① 全ポリシーに共通する1つの問い ——「既存インスタンスをどうするか」
- 既定値は All at once(全台同時)。ただし EB CLI で --single を付けずに作ったスケーラブル環境は既定が Rolling になる(公式:「By default, your environment uses all-at-once deployments. If you created the environment with the EB CLI and it's a scalable environment (you didn't specify the --single option), it uses rolling deployments.」)
- 「箱の中身を入れ替える」= 既存EC2の上でアプリを差し替える(All at once / Rolling / Rolling with additional batch)。「箱ごと替える」= 新インスタンスを丸ごと別のAuto Scalingグループに立てる(Immutable / Traffic splitting)
5つのポリシーの違いは装飾ではなく、「稼働中のインスタンスに手を入れるか、無傷のまま横に新品を建てるか」という1つの分岐から派生する。この分岐が、以降のすべてのトレードオフ(ダウンタイム・コスト・ロールバックの容易さ)を決める。
② 箱の中身を入れ替える3種 —— 速さと容量のトレードオフ
- Rolling は各バッチをロードバランサーから外し、アプリを差し替え、再アタッチ後にバッチ内の全インスタンスが「健康」と判定されるまで待ってから次のバッチへ進む(公式:「Each batch is taken out of service during the deployment phase, reducing your environment's capacity by the number of instances in a batch.」)
- Rolling with additional batch は「first launch a new batch of instances to ensure full capacity during the deployment process」。完了後に追加バッチを終了する
この3つは同じ「箱の中身を入れ替える」系で、追加インスタンスを1バッチ払うかどうかだけが違う。追加バッチを払えば容量低下を消せる——速さ・容量・コストの三角形の中で、どこにお金を置くかの選択にすぎない。
③ 箱ごと替える —— Immutable が「混在状態」を根絶する
- 公式の売り文句:「Immutable deployments can prevent issues caused by partially completed rolling deployments. If the new instances don't pass health checks, Elastic Beanstalk terminates them, leaving the original instances untouched.」
- 注意:全インスタンスを置き換える操作では、蓄積した EC2 のバーストバランス(T系インスタンスのCPUクレジット等)が失われる、と公式が警告している。対象は Immutable / Traffic splitting のデプロイに加え、Immutable更新、インスタンス置換を有効にしたマネージドプラットフォーム更新も含む
Immutable の価値は「部分適用が原理的に起きない」こと。旧群には最後まで手を触れないので、失敗しても捨てるのは新群だけ。これはコンテナ編のイミュータブルなイメージ・キャッシュ編のバージョン付きファイル名と同じ「作り直して差し替える」原則の3回目の登場であり、ここで一般法則に昇格する——状態を書き換えず、新しい状態を横に作って切り替える。
④ Traffic splitting —— 箱ごと替える上に「カナリア評価」を挟む
- ALB が必須(公式:「Traffic-splitting deployments require an Application Load Balancer.」)。EBはコンソール/EB CLI で環境を作ると既定でALBを使う
- 容量は増減しない:公式注記「The environment's capacity doesn't change during a traffic-splitting deployment.」——一時ASGには開始時点の元ASGと同数のインスタンスを立て、期間中は両ASGの台数を一定に保つ(評価時間を設定する際に考慮せよ、との注意付き)
- 中止は AbortEnvironmentUpdate API / コンソールの「Environment actions → Abort current operation」で可能。ロールバックは「quick and doesn't impact service to client traffic」
Traffic splitting は Immutable の「新群を横に建てて、ダメなら捨てる」構造をそのまま使い、切り替えを一発ではなく「一部トラフィック→評価→全切り替え」の2段にしたもの。だから Immutable の安全性(旧群無傷)を保ったまま、新バージョンを本番トラフィックで試せる。DVAでは Rolling=段階的ローリング、Immutable=Blue/Green、Traffic splitting=カナリア、という対応がそのまま問われる。
⑤ ロールバックの分かれ道 ——「混在状態」が生まれるのは Rolling だけ
- Rolling の失敗(公式):「If a deployment fails after one or more batches completed successfully, the completed batches run the new version ... while any pending batches continue to run the old version.」→ 戻すには「perform another deployment with a fixed or known good version of your application to roll back.」
- All at once にも自動ロールバックはなく、失敗時は既知の良いバージョンを再デプロイして戻すのが基本手順(その再デプロイにも再び短時間の停止が伴う)
- Immutable / Traffic splitting は新群を破棄するだけなので、既知バージョンの再デプロイは不要
「混在状態」は、部分的に適用された更新がロールバックされずに残るという、トランザクションの原子性(all-or-nothing)が欠けたときに起きる典型的な事故だ。Immutable と Traffic splitting は「新しい箱を丸ごと採否する」ことで更新を原子的に近づけ、この事故そのものを設計から消している——メッセージング編の配信保証で見た「途中まで進んだ処理をどう扱うか」と同じ問題の、デプロイ版。
⑥ 設定の実体は .ebextensions の option_settings —— そして締めの比較
- aws:elasticbeanstalk:command の既定値と範囲: DeploymentPolicy 既定 AllAtOnce(AllAtOnce | Rolling | RollingWithAdditionalBatch | Immutable | TrafficSplitting)/ BatchSizeType 既定 Percentage(Rolling系のみ)/ BatchSize 既定 100(Percentageなら1〜100、Fixedなら1〜ASGのMaxSize)/ IgnoreHealthCheck 既定 false(失敗してもロールバックせず次へ)/ Timeout 既定 "600"秒・範囲1〜3600(健康待ちの制限時間。EBが内部で240秒を加算するため、既定600秒の実効タイムアウトは840秒=14分)
- aws:elasticbeanstalk:trafficsplitting: NewVersionPercent 既定 10・範囲1〜100(最初に新へ流す割合)/ EvaluationTime は分単位・既定 5・範囲3〜600(全切り替え前の評価時間)
- HealthCheckSuccessThreshold(既定 Ok、有効値 Ok | Warning | Degraded | Severe。健康とみなす閾値を下げる)の設定リファレンス上の正式な所属は aws:elasticbeanstalk:healthreporting:system 名前空間。ただしデプロイポリシー頁の公式サンプルは aws:elasticbeanstalk:command: 配下に記載しており、本レッスンもそれに合わせた
- 健康関連オプション3つ: Ignore health check(バッチが Command timeout 内に健康化しなくてもデプロイをロールバックさせず続行)/ Healthy threshold(=HealthCheckSuccessThreshold。Warning など低いステータスでも健康とみなす)/ Command timeout(=Timeout。健康待ちの秒数。Ignore health check 有効時は次バッチへ進む)
- 公式サンプル値: Rolling は BatchSizeType: Percentage / BatchSize: 25、Rolling with additional batch は Fixed / 5、Immutable は HealthCheckSuccessThreshold: Warning / IgnoreHealthCheck: true / Timeout: "900"(15分)、Traffic splitting は NewVersionPercent: "15" / EvaluationTime: "10"。注意: EB CLI とコンソールはこれらのオプションに推奨値を自動適用するため、設定ファイルで同じ項目を管理したい場合はそれらの設定を外す必要がある
- 5ポリシー比較の要点: ダウンタイムがあるのは All at once だけ(全台短時間)。容量低下があるのは All at once と Rolling(バッチ分)。追加インスタンスコストは Rolling+batch が1バッチ分(一時)、Immutable / Traffic splitting が完全な新群(一時)。失敗時に混在状態→既知バージョン再デプロイが必要なのは All at once / Rolling系、新群破棄だけで済むのは Immutable / Traffic splitting。ALB必須は Traffic splitting のみ
5つのポリシーは別々の機能ではなく、「速度・追加コスト・ダウンタイム・容量低下・失敗時の戻し方」という同じ5軸の上に置かれた5つの点だ。軸を上から下へ辿るほど「速さと安さ」を手放して「安全さ(中断ゼロ・原子的ロールバック)」を買っている——これがこのレッスンの一般法則。