
変更のたびに本番 (prod) へデプロイするのは怖いかもしれません。しかし、本番に直接デプロイできないことのほうがもっと怖いのです。
これは、私が Amazon で何億人もの顧客にサービスを届けるチームを率いていたときに実践していたプロセスです。また、コンサルティングを通じて、隔週のスケジュールリリースでデプロイしていたエンジニアリングチームを、マージごとに本番反映する体制へと導いてきました。
まず、誰もが認める当然の事実から始めましょう。
あなたは必ず障害を起こします。起こるかどうかではなく、いつ起こるかという問題です。
ユニットテスト、統合テスト、ドッグフーディング、エンドツーエンドの何やら、デプロイの神様への生贄。これらをどんなに積み重ねても、すべてのバグを捉えることはできません。
1 週間前にあなたの機能に対して行ったテストは、チームメイトの最新の変更と組み合わせてテストされたものではありません。
あなたのテストは、チームメイトのサービスの pre-prod バージョンに対して行われたものです。しかし、そのサービスはすでに変更されており、後方互換性のない変更が含まれています。
待てば待つほど、1 つのリリースに積み重なる変更が増えていきます。ロールバックが必要になった場合、1〜2 時間分の変更ではなく、2 週間分の変更をロールバックしなければなりません。
障害が避けられないという前提を受け入れるなら、リリースの QA に多大なリソースを割く合理性ははるかに小さくなります。むしろ、リリースのモニタリングと監視にリソースを集中させ、障害が発生したときに備えるべきです。
では、どうやってそこに到達するのかを見ていきましょう。
前提条件
CI/CD
テストは、あなたが思っているほど重要ではありません。テストは、あなたの変更が本番環境で安全であることを証明できません。何も証明できないのです。テストがもたらすのは、失敗を安価にすることです。CI で見つかったバグは数分のコストで済みます。本番で見つかったバグは、ロールバック作業で夜を潰すコストがかかります。
だからこそ、マージのたびに、あるいは少なくともパイプラインの一部として、フルスイートを実行しましょう。ユニットテスト、統合テスト、エンドツーエンドテストです。バグがパイプラインの下流へ進めば進むほど、解決にかかるコストは高くなります。
モニタリング / 可観測性
最も重要なのは、リグレッションをできるだけ早く検知できることです。そのためには、優れたモニタリングが不可欠です。具体的には次のようなものが必要です。
- メトリクス: エラー、レイテンシ、可用性
- 相関 ID 付きログ
- 上記 2 つに連動した sev-3 および sev-2 (ページング) のアラーム
アラームのしきい値の調整には、少しばかりの職人技と科学性が求められます。感度と、実際のインシデントへの対応速度のバランスが重要です。sev-2 のアラート発報までの目標時間は 5〜10 分に設定しましょう。
最初はおそらく、しきい値が間違っていて、過敏になりすぎているでしょう。残念ながら、これはほとんど試行錯誤で学んでいくものなので、最初は午前 2 時に起こされることが何度かあるはずです。
フィーチャーフラグ
リスクのある変更は、フィーチャーフラグ / リモートコンフィグの背後でリリースするべきです。フィーチャーフラグがあれば、デプロイ全体をロールバックする必要なく、変更を数分以内に無効化できます。さらに、フィーチャーフラグサービスが対応していれば (対応しているべきです)、機能を割合またはコホート単位で段階的にロールアウトでき、悪い変更の影響をさらに抑えられます。
これにより、コードのデプロイとコードの有効化を分離できます。地味な違いですが、リスク削減においてはゲームチェンジャーです。
注意: フラグをクリーンアップするためのプロセスが必要です。理想的には、作成したフラグごとに削除チケットを作成しましょう。そうしないと、フィーチャーフラグサービスがダウンしたとき (必ずダウンします) に、重大なリグレッションが発生します。なぜ私がそれを知っているのかは、聞かないでください。
自動ロールバック (デプロイ時サーキットブレーカー)
デプロイ時サーキットブレーカーとは、フリート全体にロールアウトする際、エラーの数または割合を検知したらデプロイをロールバックできる機能です。現在、ほとんどのクラウドプロバイダーが、チェックボックスひとつでこれを提供しています。
後方互換性のある変更
これはすでに実践しているはずですが、コミットごとのデプロイはこの実践を必須にします。ローリングデプロイ中は、旧バージョンと新バージョンが同時に実行されることになります。すべての変更は、以前のバージョンと共存して動作する必要があります。これを回避するための真夜中デプロイという裏技は、もはや通用しません。
デプロイ戦略
では、これらを整えたうえで、変更をロールアウトする際のリスクを軽減する、いくつかのデプロイ戦略を見ていきましょう。
ワンボックス (カナリア)
ワンボックスデプロイは、大規模なフリートの中の 1 台のボックスに変更をデプロイする方法です。これにより、悪い変更の影響を 1 台のホストだけに抑えられます。
デプロイ後は、全体トラフィックのごく一部を受けながら、一定期間その状態を維持します。このボックスにはモニタリングとアラートを設定しておき、何か問題が起きたら発報されるようにします。
ローリングデプロイ
ローリングデプロイでは、時間をかけてパーセンテージ単位でロールアウトできます。これにより、壊滅的なエラーが発生しても、すべてのマシンに影響が広がる前に検知し、ロールバックを開始できます。
リージョン別ロールアウト
会社が成長すると、複数リージョンへのデプロイが必要になります。すべてのリージョンに同時にデプロイするのではなく、まず特定の 1 リージョン (通常は最もトラフィックの少ないリージョン) にデプロイできます。
このアプローチが当てはまらないケース
アプリストア
モバイルアプリのリリースは、このガイダンスと完全に両立するわけではありません。アプリストアのレビュー待ちがデプロイの頻度を制限するため、別の戦略が必要です。
認証が必要な環境
医療機器、航空電子機器、産業制御などです。規制当局によるビルドの認証が必要な場合、継続的デプロイはできません。
オンプレミス / セルフホステッド
アップグレードのタイミングを制御できません。運用しているすべてのものに対して継続的デプロイは可能ですが、各変更にバージョンを付け、顧客がいつ採用するかを決めることになります。
どこから始めるか
すべてを一度に行わないでください。順序が重要です。
- CI をグリーンかつ高速にする。理想的には 15 分以内
- エラー率、レイテンシ、可用性に関するメトリクスとアラームを設定する。これがこの取り組みで最も重要な部分です
- リスクのある変更はすべてフラグの背後に置く
- ワンボックス + 自動ロールバックを追加する
- リリースカレンダーを削除する
- リリースのスケジューリングをしなくなってできた時間の新しい使い道を見つける
私が一緒に仕事をしたほとんどのチームは、これをやり遂げるのに約 1 クォーター (四半期) かかりました。ツールの導入は簡単な部分です。難しいのは、組織のプロセスと、スケジュールリリースが安全だという幻想を打ち破ることです。
あなたのチームがリリースカレンダーに縛られていて、そこから抜け出したいのなら、それがまさに私の仕事です。DM してください。





