ステージング環境に独自のデプロイメントゲートが必要な理由

開発者がメインブランチに変更をプッシュする。ビルドは成功し、単体テストはグリーン。パイプラインは自動的にステージング環境へデプロイする。QAテスターが新機能の検証を始めたが、途中でステージング環境が壊れてしまう。原因は別のチームが先にデプロイした変更によるコンフリクトだった。QAは何もテストできなくなり、リリーススケジュールは遅れ、誰もどのデプロイが問題を引き起こしたのかわからない。

この状況は、多くのチームが想定するよりも頻繁に発生する。ステージングを「何でもありのカジュアルな環境」として扱いたくなるのが人情だ。しかし、検証が行われる場であるステージングが壊れれば、デリバリープロセス全体が止まってしまう。問題は、「すべての環境を同じように扱うべきか」という点にある。

一律のデプロイルールが抱える問題

すべての環境に同じパイプラインルールを適用すると、次の2つのうちどちらかが起こる。ルールが本番環境には緩すぎるか、開発環境には厳しすぎるかだ。どちらも良い結果にはならない。

本番レベルの管理を開発環境に適用すると、開発者はその段階では価値のない承認やスキャンを待たされる。逆に、開発レベルの管理を本番環境に適用すると、適切に検証されていない変更をデプロイするリスクが生じる。

本当の問題は、環境ごとに目的が異なることだ。開発は実験のため、ステージングは検証のため、本番は実際のユーザーのため。それぞれの目的には異なるレベルのリスクが伴い、パイプラインはそれを反映すべきである。

プロテクト環境とは何か

プロテクト環境とは、特定のゲートを通過しなければデプロイできない環境のことである。これらのゲートは、自動チェック、手動承認、またはその両方で構成される。重要なのは、保護がパイプラインのステージではなく、環境に紐づいている点だ。

本番環境が保護の対象となるのは明白だ。しかし、ステージングも保護に値する場合が多い。特に複数のチームが共有していたり、QAがリリース検証に依存している場合だ。ステージング環境が壊れれば、本番環境が壊れたときと同じようにリリースが遅延する。

保護は二値的ではない。単に環境を「保護あり」「保護なし」とマークするわけではない。代わりに、各環境にどのゲートを適用するかを定義する。ここで環境固有のゲートが登場する。

環境固有のゲートの実践

環境固有のゲートとは、特定の環境にのみ適用されるチェックまたは承認のことである。同じパイプラインでも、環境ごとに異なるゲートを設定できる。

典型的な例を示す。

  • 開発環境: ビルド成功、単体テスト合格。手動承認は不要。
  • ステージング環境: 統合テスト合格、セキュリティスキャン完了、ピア承認1件。
  • 本番環境: 回帰テスト合格、セキュリティスキャン完了、シニアエンジニアによる承認2件、コンプライアンスチェック。

パイプライン設定は、これらのゲートを環境ごとに定義する。変更がある環境から次の環境に移行するとき、パイプラインは対象環境のゲートをチェックしてから処理を進める。

このアプローチにより、下位環境ではフィードバックループを高速に保ちつつ、上位環境では安全性を維持できる。開発者は初期テスト中に不要な承認を待つ必要がない。しかし、本番環境への変更は適切な検証なしには通過できない。

環境間のプロモーションの仕組み

プロモーションとは、変更をある環境から次の環境に移す行為である。例えば、ステージングから本番へのプロモーション。両方の環境がプロテクトされている場合、プロモーションには対象環境のゲートを通過する必要がある。

以下の図は、変更が各境界で異なるゲートを通過しながら環境を移動する様子を示している。

flowchart TD Dev[開発環境] -->|自動プロモーション| StagingGates{ステージングゲート} StagingGates -->|自動チェック合格| StagingApproval{手動承認?} StagingApproval -->|ピア承認| Staging[ステージング環境] StagingApproval -->|却下| Fail1[ブロック] Staging -->|プロモーション| ProdGates{本番ゲート} ProdGates -->|厳格なチェック合格| ProdApproval{シニア承認?} ProdApproval -->|2件の承認| Production[本番環境] ProdApproval -->|却下| Fail2[ブロック]

ただし、ステージングへのプロモーションのゲートは、本番へのプロモーションのゲートよりも軽量であることが一般的だ。これは意図的な設計である。変更を迅速にステージングに到達させ、早期に検証を開始したいからだ。本番環境には、徹底的な検証を経た変更だけを届けたい。

よく使われるパターンは、すべての自動ゲートをパイプラインの早い段階で実行し、手動承認は本番環境の前でのみ一時停止するというものだ。ステージングは自動ゲートを通過するが、手動待機はスキップする。これにより、スピードと安全性のバランスが取れる。

承認者は環境によって異なる

すべての承認が同等というわけではない。開発環境への変更を開発者が承認するのは妥当だ。しかし、同じ変更が本番環境に進む場合、テックリードやエンジニアリングマネージャーの承認が必要になるかもしれない。

データベースの変更であれば、DBAの承認が必要かもしれない。インフラストラクチャの変更であれば、プラットフォームチームの承認が必要かもしれない。パイプラインは、各環境に対して誰が承認権限を持つかを認識し、すべての承認を証跡として記録すべきである。

これは官僚主義の問題ではない。責任範囲に影響を与える変更について、適切な人物が認識していることを確実にするためだ。DBAはすべてのコード変更を承認する必要はないが、データベースマイグレーションが本番環境に向かっていることは把握しておくべきである。

環境固有のゲートを設定するための実践的チェックリスト

チームでこれを実装する場合、以下の短いチェックリストが役立つ。

  • チームが使用するすべての環境をリストアップする(開発、ステージング、本番など)
  • 各環境について、不適切なデプロイのリスクを洗い出す
  • そのリスクを軽減するために必要な最小限のゲートを定義する
  • 各環境の変更を承認できる人物を決める
  • パイプラインを設定して、環境ごとにこれらのゲートを強制する
  • 各環境へのデプロイをシミュレーションしてゲートをテストする
  • チームやアプリケーションの進化に合わせて、定期的にゲートを見直す

このチェックリストは網羅的ではないが、出発点としては十分だ。目標は、ゲートを追加すること自体ではなく、比例した制御を適用することにある。

まとめ

プロテクト環境と環境固有のゲートにより、デリバリーパイプラインの各段階に適切なレベルの制御を適用できる。ステージングは信頼性を保つための十分な保護を得る。本番は、問題がユーザーに届く前に捕捉するための多層的な保護を得る。開発は、同じ負荷を負わないため、スピードを維持できる。

重要なのは、同じルールをどこにでもコピーすることではない。各環境に何が必要かを理解し、それに基づいてパイプラインを構築することだ。これを正しく実現できれば、チームはスピードが重要な場面では速く動き、安全性が重要な場面では慎重に動くことができる。