デプロイパイプラインにおいて手動承認が依然として重要な理由
パイプラインはグリーンです。すべての自動チェックが通過しました。ビルドはエラーなくコンパイルされ、ユニットテストは成功し、セキュリティスキャンで深刻な脆弱性は見つからず、統合テストでもAPIが正しく応答することを確認できました。パイプラインは本番環境へのデプロイ準備が整っています。
しかし、何かが引っかかります。この変更は決済モジュールを書き換えるものです。自動テストはコードが動作することを検証しますが、新しい決済フローがビジネスチームが銀行と合意した内容と一致するかどうかは教えてくれません。パイプラインは構文が正しいことはわかりますが、ロジックが正しいかどうかはわかりません。
これこそが、自動化の限界に達する瞬間です。
自動化ゲートでは見えないもの
自動化ゲートは、機械的な問題を検出するのに優れています。コンパイルエラー、テストの失敗、セキュリティ設定ミス、構文ミスをキャッチします。毎回同じチェックを一貫して、疲れることなく実行します。
しかし、機械はビジネスへの影響を評価できません。パイプラインはコードが変更されたことを検出できますが、その変更が重要なビジネスフローを変えるかどうかは判断できません。パイプラインはデータベースマイグレーションスクリプトの構文が正しいことを検証できますが、そのマイグレーションが本番環境で大きなテーブルをロックし、ダウンタイムを引き起こすかどうかは予測できません。パイプラインはサーバー設定ファイルが有効なJSONであることを確認できますが、その設定が別のサービスの依存関係を壊すかどうかはわかりません。
これらは、人間の判断が必要となる状況です。問題は、すべてを自動化するかどうかではありません。問題は、どの変更がユーザーに届く前に人間の目を通す必要があるかです。
手動承認が必要な4つの状況
大規模なアプリケーションコードの変更
変更の規模はコード行数で測られるものではありません。フィーチャーフラグを切り替える1行の変更は低リスクかもしれません。一方、コアモジュールを書き換える変更は、触れるファイルが少なくても高リスクになり得ます。
手動承認が重要になるのは、変更が重要なビジネスフローに影響を与える場合です。決済モジュールの書き換え、ユーザーセッションの処理方法の変更、アプリケーションの多くの部分が依存するコアライブラリの置き換え — これらの変更には、自動テストでは完全に評価できないリスクが伴います。テストは新しいコードがクラッシュしないことを検証できますが、新しいビジネスロジックがチームがステークホルダーと合意した内容と一致することを確認することはできません。
ビジネスコンテキストを理解している誰かが変更をレビューし、「これは私たちが計画したものと一致している」と判断する必要があります。
データベースの変更
データベースの変更は、本番インシデントの最も一般的な原因の1つです。スキーマ変更、新しいインデックス、データマイグレーションには、自動的に検出するのが難しい副作用があります。
次のGitHub Actionsワークフロースニペットは、データベースマイグレーションの変更に対して手動承認を要求する方法を示しています。
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
# Require manual approval for changes under migrations/
if: contains(github.event.head_commit.modified, 'migrations/')
steps:
- uses: actions/checkout@v4
- name: Run database migration
run: |
echo "Applying migration..."
# Migration script goes here
この例では、environment: production 設定により、GitHub Actionsで手動承認ステップがトリガーされます。パイプラインは、指定されたレビューアがデプロイを承認するまで一時停止し、マイグレーションが本番環境に到達する前に人間が評価することを保証します。
大きなテーブルにカラムを追加するマイグレーションは、そのテーブルを数分間ロックし、アプリケーションが応答しなくなる可能性があります。パイプラインはマイグレーションの構文が有効かどうかをチェックできますが、本番データ量に対して安全に実行できるかどうかを評価することはできません。開発環境の1000行のデータベースで問題なく動作するクエリが、数百万行の本番データベースではパフォーマンスが著しく低下する可能性があります。
データベースチームまたはシニア開発者がマイグレーションプランをレビューし、その影響を見積もり、安全に実行できることを承認する必要があります。これはゲートキーピングの問題ではありません。アプリケーション全体をダウンさせる5分間のテーブルロックを防ぐことです。
インフラストラクチャの変更
インフラストラクチャの変更は、予測が難しい波及効果をもたらすことがよくあります。ネットワークファイアウォールルールの変更、インスタンスタイプの切り替え、Kubernetesバージョンの更新、ロードバランサー設定の変更は、そのインフラに依存しているとは知らなかったサービスに影響を与える可能性があります。
典型的な例:ファイアウォールルールを変更した結果、誤って別のチームのサービスからのトラフィックをブロックしてしまう。または、ロードバランサーの設定を変更した結果、リクエストが間違ったバックエンドにルーティングされる。パイプラインは設定ファイルが構文的に正しいことを検証できますが、その設定が本番環境で実際に動作しているアーキテクチャと一致するかどうかはわかりません。
インフラストラクチャチームは変更をレビューし、依存関係をチェックし、適用しても安全であることを確認する必要があります。
本番環境へのあらゆる変更
本番環境は、実際のユーザーがアプリケーションとやり取りする場所です。ここでのすべての変更は直接的なリスクを伴います。一見小さな変更 — エラーメッセージの更新、フォントサイズの調整、ログレベルの変更 — でも、予期しない副作用が発生する可能性があります。
多くのチームはシンプルなルールを採用しています。変更の種類に関係なく、手動承認なしでは本番環境に変更を加えない。このルールはあいまいさを排除します。すべての本番変更を誰かが確認し、責任を負うことを強制します。
承認が必要な変更の判断方法
すべての変更に人間のレビューが必要なわけではありません。ドキュメントページのタイポ修正や新しいログステートメントの追加は、通常、自動化ゲートを通しても安全です。しかし、データベーススキーマの変更、本番設定の変更、コアビジネスフローに影響を与える変更には、手動承認が必要です。
一般的なパターンは、変更をリスクレベルで分類することです。
次のフローチャートは、判断プロセスをまとめたものです。
低リスク変更: 重要でない機能のバグ修正、ドキュメント更新、監視の追加、機能に影響しない設定値の変更。これらは手動レビューなしで自動化ゲートを通過できます。
高リスク変更: データベーススキーマ変更、本番設定の変更、コアビジネスロジックの変更、破壊的変更を伴うライブラリのアップグレード、または重要なフローでユーザーに影響を与える変更。これらには手動承認が必要です。
チームは、アプリケーションのコンテキストと過去の経験に基づいて境界を定義できます。重要なのは、誰もが何に承認が必要で、何に必要でないかを明確に分類することです。
手動承認設定のための実践的チェックリスト
- アプリケーションのコンテキストで何が高リスクかを定義する。過去にインシデントを引き起こした変更から始めるとよい。
- 可能な場合は変更を自動的に分類する。コミットメッセージ、ファイルパス、ブランチ名を使用して、高リスク変更にフラグを立て、手動レビューをトリガーする。
- 専門知識に基づいて承認者を割り当てる。データベース変更はDBAチームへ。インフラ変更はプラットフォームチームへ。ビジネスロジック変更はドメインを理解しているシニア開発者へ。
- 妥当な時間枠を設定する。手動承認に数日かかるべきではない。承認者の最大応答時間を定義し、誰も応答しない場合のエスカレーションパスを用意する。
- すべての承認決定を記録する。誰が、何を、いつ、なぜ承認したかを記録する。これはインシデント後に決定をトレースバックする必要がある場合に貴重な情報となる。
手動承認の真の目的
手動承認は、デリバリーを遅くすることではありません。高リスクの変更がユーザーに届く前に、それにふさわしい注意を確実に払うことです。自動化はルーチンチェックを処理します。人間は、機械にはできない判断を下します。
目標は手動承認を排除することではありません。目標は、真に必要な変更のために手動承認を温存し、チームがそれ以外の変更では迅速に動きながら、最も重要な部分では安全性を確保することです。