デプロイ後に確認すべきこと:本番投入完了と判断する前に
パイプラインがグリーンになった。ビルド成果物がアップロードされた。デプロイスクリプトがエラーなく終了した。多くのチームはそこで止まり、新しいバージョンが問題なく動いていると思い込む。その思い込みは危険だ。
パイプラインがグリーンなのは、デリバリプロセスが技術的なエラーなく実行されたことを意味するだけだ。新しいバージョンが本番で実際に動作していることを意味するわけではない。パイプラインの成功と、デプロイが機能していることの間には、能動的に確認すべきギャップが存在する。
パイプラインの成功だけでは不十分な理由
本番環境はステージングやテスト環境とは異なる。本番では、新しいバージョンは実際のデータ、実際のトラフィックパターン、実際のネットワーク状況に直面する。パイプラインでは決して検出できないことが起こる。
- 本番データセットがステージングの10倍の大きさであるために遅くなるデータベース接続
- テストクエリでは問題ないが、実際のユーザーアクセスパターンではミスするキャッシュ設定
- デプロイスクリプトが検出しなかったサーバーの設定ミス
- 実際の負荷下で異なる応答をするサードパーティAPI
パイプラインはスクリプトを実行しコードをチェックする。システムが現実と直面したときにどう振る舞うかは知らない。だからこそ、デプロイ後に別のステップ、すなわち検証が必要なのだ。
デプロイと検証の違い
デプロイとは、新しいバージョンを環境に配置する行為である。検証とは、その環境で新しいバージョンが期待通りに動作することを確認する行為である。
これらは異なる活動だ。デプロイはマシンとスクリプトに関するものだ。検証は振る舞いとシグナルに関するものだ。多くのチームはこれらを同一視するか、パイプラインがすべて問題ないと言ったからといって検証を完全にスキップする。
次のフローチャートは、デプロイと検証が別々のトラックであり、デプロイ完了と見なす前に両方が成功しなければならないことを示している。
スクリプトが終了した時点でデプロイが完了したと見なす瞬間、本番で予期せぬことが何も起こらないという賭けをしていることになる。単純な変更であれば、その賭けに勝つかもしれない。しかし、データベースマイグレーション、設定変更、インフラストラクチャ更新が絡む場合、勝ち目は薄い。
スモークテストから始める
最も基本的な検証ステップはスモークテストだ。この用語はハードウェア工学に由来する。新しいデバイスに初めて電源を入れたとき、煙が出るかどうかを確認する。煙が出なければ、少なくともデバイスは発火しなかったということだ。
ソフトウェアデプロイにおいて、スモークテストは新しいバージョンが生きていて応答するかどうかを素早く確認するものだ。これは一つの問いに答える。このバージョンはリクエストを受け付け、妥当な応答を返せるか?
実用的なスモークテストには以下が含まれる。
以下は、デプロイされたエンドポイントに対してスモークテストを実行し、失敗時にゼロ以外のコードで終了する最小限のbashスクリプトである。
#!/bin/bash
# smoke-test.sh - Quick check that the deployed version is alive
URL="https://your-app.example.com/health"
EXPECTED_STATUS=200
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
if [ "$HTTP_STATUS" -ne "$EXPECTED_STATUS" ]; then
echo "Smoke test failed: expected status $EXPECTED_STATUS, got $HTTP_STATUS"
exit 1
fi
echo "Smoke test passed: $URL returned $HTTP_STATUS"
exit 0
- メインページにアクセスし、200レスポンスを確認する
- シンプルなAPIエンドポイントを呼び出し、レスポンス構造を検証する
- データベース接続が生きていることを確認する
- 静的アセットが正しく読み込まれることを確認する
スモークテストは深くある必要はない。明らかな障害をキャッチするための高速で浅いチェックだ。スモークテストが失敗したら、何か深刻な問題があることがわかり、それ以上のトラフィックを止めるかロールバックする必要がある。合格したら、より詳細なチェックに進むことができる。
基本シグナルを確認する
スモークテストが合格したら、システムの運用シグナルを確認する。これらは、新しいバージョンが正常に動作しているか、問題を引き起こしているかを教えてくれるメトリクスだ。
必要なシグナルは何をデプロイしたかによって異なるが、普遍的なものもある。
- エラー率: デプロイ前と比べて失敗したリクエストの割合が高いか?
- レイテンシ: 応答時間が許容範囲内か?突然のスパイクはしばしば問題を示す。
- リソース使用量: デプロイ後にCPU、メモリ、ディスク使用量が大幅に変化したか?
- トラフィック量: システムは期待通りのリクエスト数を受信しているか?突然の低下は、ユーザーが新しいバージョンに到達できないことを意味するかもしれない。
これに複雑な分析は必要ない。現在の値をデプロイ前の同じ時間枠と比較する。モニタリングダッシュボードがあれば、この比較は数分で完了する。
重要なのは、このチェックをデプロイプロセスの標準的な一部にすることだ。思い出したときや誰かが問題を報告したときだけ行うものではない。
検証はデプロイの一部である
ここで考え方を変えてほしい。検証はデプロイ後に発生する別の活動ではない。検証はデプロイそのものの一部だ。新しいバージョンが正常に動作しているという十分な確信が得られるまで、デプロイは完了していない。
これはパイプラインに実用的な影響を与える。パイプラインはスクリプトが終了した時点でデプロイを成功とマークすべきではない。検証が合格するまで待つべきだ。検証が失敗した場合、スクリプトがエラーなく実行されたとしても、パイプラインはデプロイを失敗として報告すべきだ。
一部のチームは、デプロイ後にパイプラインを一時停止し、手動確認を待つことでこれを実装している。他のチームはスモークテストと基本シグナルチェックを自動化し、それらのチェックが合格した場合にのみ成功とマークする。どちらのアプローチも、すべて問題ないと思い込むよりはるかに優れている。
変更の種類によって必要なチェックは異なる
すべてのデプロイが同じではない。アプリケーションの更新、データベースマイグレーション、インフラストラクチャの変更には、それぞれ異なるリスクと確認すべきシグナルがある。
アプリケーション更新の場合、主なリスクはリクエスト処理、応答の正確性、既存サービスとの統合に関するものだ。スモークテストとエラー率のチェックで通常は十分だ。
データベースマイグレーションの場合、リスクは異なる。マイグレーションが正しく実行されたこと、データ整合性が保たれていること、クエリパフォーマンスが低下していないことを確認する必要がある。シグナルチェックには、データベース接続プールの使用状況、クエリレイテンシ、該当する場合はレプリケーションラグを含めるべきだ。
インフラストラクチャ変更の場合、リスクは接続性、リソース可用性、設定の正確性に関するものだ。シグナルチェックには、ネットワークレイテンシ、証明書の有効性、サービスディスカバリのステータスを含めるべきだ。
原則は同じだ。この特定の種類の変更で何が問題になる可能性があるかを特定し、デプロイ完了と呼ぶ前にそれらをチェックする。
実用的なデプロイ後チェックリスト
具体的に始められるものが欲しいなら、以下はほとんどのWebアプリケーションで機能する最小限のチェックリストだ。
- スモークテスト合格:メインページ、重要なAPIエンドポイント、データベース接続
- エラー率がデプロイ前より高くない
- レイテンシが通常範囲内
- CPUとメモリ使用量が安定している
- アプリケーションログに異常なログやエラーメッセージがない
- データベースマイグレーションが含まれる場合:マイグレーションステータスが成功、クエリパフォーマンスが正常
このチェックリストは網羅的ではないが、基本をカバーしている。特定のシステムにとって最も重要なシグナルを学ぶにつれて、拡張できる。
まとめ
パイプラインがグリーンでも、デプロイが成功したとは限らない。パイプラインはデリバリの仕組みを処理する。検証は新しいバージョンが実際に機能するかという現実を処理する。新しいバージョンが本番で正常に動作していることを確認するまで、デプロイは完了したと見なしてはならない。この習慣一つで、ユーザーが気づく前に問題をキャッチできる。