デプロイメントとリリースの違い:ユーザーが実際に新バージョンを使うタイミング

チームがバージョン1.2.0を本番環境にデプロイし終えたとします。アーティファクトはサーバーに配置され、アプリケーションは稼働し、すべてのヘルスチェックが正常を示しています。これで全ユーザーが新機能を使えるようになったのでしょうか?おそらく違います。

チームが意図的に特定の機能を隠して安定性を監視しているかもしれません。あるいは、デプロイ先のサーバーがまだユーザーに接続されていない可能性もあります。「コードが動いている」状態と「ユーザーが使える」状態の間には、多くのチームが考えている以上にギャップがあります。

デプロイメントとリリースの違い

デプロイメントは技術的なアクションです。アーティファクトを環境に配置し、それを実行可能にします。サーバーは新しいバイナリを受け入れ、データベースマイグレーションが完了し、アプリケーションがリクエストに応答し始めます。インフラストラクチャの観点からは、仕事は完了です。

次のフローチャートは、デプロイメントとリリースがどのように分岐するかを示しています:

flowchart TD A[コードコミット] --> B[ビルド & テスト] B --> C[本番環境にデプロイ] C --> D{リリース戦略は?} D -->|フィーチャーフラグ| E[フィーチャーフラグOFF] D -->|カナリア| F[5%のトラフィックをルーティング] D -->|ブルーグリーン| G[非アクティブ環境にデプロイ] E --> H[ユーザー向けにフラグを有効化] F --> I[監視して割合を増加] G --> J[トラフィックを切り替え] H --> K[ユーザーが機能にアクセス] I --> K J --> K style C fill:#4a90d9,color:#fff style K fill:#27ae60,color:#fff

リリースはビジネス上の判断です。機能や修正が実際にユーザーにとって利用可能になる瞬間です。デプロイメントはリリースなしで発生し得ますが、リリースはデプロイメントなしでは発生しません。

この区別が重要なのは、リスクの考え方が変わるからです。デプロイメントとリリースが同じものである場合、すべてのデプロイメントにユーザー影響の全責任が伴います。これらを分離することで、対応の余地が生まれます。

フィーチャーフラグ:最もシンプルな分離方法

フィーチャーフラグは、デプロイメントとリリースを切り離す最も一般的な方法です。再デプロイせずに機能のオン/オフを切り替えられるコードを追加します。新しいバージョンが本番環境に配置され、複数の機能を含んでいますが、小規模なユーザーグループに対してのみ1つの機能が有効になっています。

以下は、YAMLファイルでのフィーチャーフラグ設定の簡単な例です:

# config/feature-flags.yaml
features:
  new-checkout:
    enabled: false
    description: "1ページ決済による新しいチェックアウトフロー"
    rollout_percentage: 0
  dark-mode:
    enabled: true
    description: "全ユーザー向けダークモード切り替え"
    rollout_percentage: 100

チームが新しいチェックアウトをリリースする準備ができたら、enabled: falseenabled: true に変更し、ロールアウト率を更新します。コード変更も再デプロイも不要で、即座に反映される設定変更だけです。

機能がうまく動作すれば、より多くのユーザーに開放します。問題が発生した場合は、フラグをオフにします。ロールバックも緊急デプロイも不要で、アプリケーションの他の部分は通常通り動作し続けます。

このパターンは、頻繁にデプロイするチームに特に有効です。未完成の機能を公開する心配をせずに、1日に複数回デプロイできます。フラグが安全スイッチの役割を果たします。

カナリアリリース:実際のトラフィックでテストする

カナリアリリースは、さらに分離を進めます。新しいバージョンを本番環境にデプロイしますが、ユーザーのごく一部(例えば5%)だけにルーティングします。このグループだけが新しいコードを体験し、他のユーザーは古いバージョンのままです。

その小グループのエラー率、応答時間、ユーザー行動を監視します。すべて正常であれば、徐々に割合を増やします。問題が発生した場合は、すべてのトラフィックを古いバージョンに戻します。ロールバックもダウンタイムも不要です。

主な利点は、合成テストではなく実際のトラフィックでテストできることです。実際のユーザーは実際のブラウザ、実際のネットワーク状況、実際の使用パターンを持っています。カナリアリリースは、ステージング環境では決して発見できない問題を捉えます。

ブルーグリーンデプロイメント:インフラレベルでの分離

ブルーグリーンデプロイメントは、インフラストラクチャレベルでリリースとデプロイメントを分離します。2つの同一の本番環境(ブルーとグリーン)を維持します。古いバージョンはブルーで動作しています。新しいバージョンをグリーンにデプロイしますが、ブルーは依然として全ユーザーにサービスを提供しています。

グリーンが安定していると確信できたら、トラフィックをブルーからグリーンに切り替えます。リリースはデプロイメント完了時ではなく、トラフィック切り替えの瞬間に行われます。切り替え後に問題が発生した場合は、トラフィックをブルーに戻します。

このパターンは、フィーチャーフラグを簡単に使えないアプリケーションや、変更が根本的すぎてフラグで切り替えられない場合に有用です。データベーススキーマ変更、メジャーフレームワークアップグレード、インフラストラクチャ変更などは、ブルーグリーンデプロイメントの恩恵を受けやすいです。

デプロイメントとリリースを分離する意義

分離により、タイミングをコントロールできるようになります。トラフィックが少ない午前2時にデプロイし、チームが監視できる朝までリリースを遅らせることができます。ユーザーを混乱させる心配なく、1日に複数回デプロイできます。リリースは別の判断だからです。

また、問題への対処方法も変わります。デプロイメントとリリースが結合している場合、悪いデプロイメントはユーザーが即座にエラーを目にすることを意味します。分離されていれば、ユーザーに影響が出る前に問題を検出する時間があります。デプロイメントのヘルスシグナルはサーバーが動いていることを示し、リリース後のシグナルはユーザーが満足していることを示します。

リリース後に監視すべきこと

リリースは、ユーザーが変更を体験し始める瞬間です。リリース前はすべてが制御下にあります。リリース後はユーザーが関与します。問題があれば、ユーザーが最初に感じます。

デプロイメント中に正常に見えたヘルスチェックは、全体像を語らないかもしれません。アプリケーションは動いていますが、ユーザーはタスクを完了できていますか?エラー率は実際に低いのか、それとも監視がカバーしていないアプリケーションの部分でエラーが発生していませんか?実際のユーザー負荷の下でパフォーマンスは安定していますか?

リリース後は異なる監視が必要です。ユーザー向けのメトリクス(ページ読み込み時間、トランザクション完了率、機能別エラー率)を監視し、リリース前のベースラインと比較します。デプロイメントが正常でもリリースが悪ければ、結果は悪いままです。

次回リリースのための実践的チェックリスト

リリース完了と判断する前に、以下のチェックを実行してください:

  • 再デプロイせずにロールバックできますか?できない場合、ロールバック計画はありますか?
  • 新しいバージョンをどのユーザーが見ているか把握していますか?カナリアリリースの場合、トラフィック分割が機能していることを確認してください。
  • サーバーヘルスだけでなく、ユーザー向けメトリクスを監視していますか?サーバーヘルスはアプリが動いていることを示します。ユーザーメトリクスはアプリが機能していることを示します。
  • 再デプロイせずに機能を無効化する方法はありますか?フィーチャーフラグを使っていない場合、次回リリース前に追加を検討してください。
  • リリースが行われたことを誰に知らせる必要がありますか?サポートチーム、ドキュメント作成者、その他のステークホルダーに通知する必要があります。

まとめ

デプロイメントはコードをサーバーに配置することです。リリースは機能をユーザーの手に届けることです。これらを別々の判断として扱うことで、自信を持ってデプロイし、慎重にリリースし、問題が発生した場合に迅速に回復する能力を得られます。優れたチームは単にデプロイが上手いだけでなく、リリースも上手いのです。なぜなら、この2つが同じではないことを理解しているからです。