ロールバック後の検証:復旧が実際に機能したことを確認する方法
ロールバックボタンを押した瞬間、エラーや応答遅延、データベース破損を引き起こしたデプロイは過去のものになりました。アプリケーションは以前のバージョンに戻り、チームは安堵の息をつきます。
しかし、システムは本当に正常に動作しているのでしょうか?
ロールバックやロールフォワードはインシデントの終わりではありません。それは中間地点です。本当の問題は、復旧自体が新たな問題を引き起こしていないか、残存データを残していないか、他のサービスとの統合を壊していないかです。復旧後の適切な検証なしにインシデント解決を宣言すると、数時間後にしか表面化しない形でシステムが壊れている可能性があります。
復旧に潜むリスク
アプリケーションをロールバックしても、単に時間を巻き戻しているわけではありません。古いバージョンは戻りますが、環境は変化している可能性があります。データベーススキーマが一致しないかもしれません。設定ファイルが新しいバージョンのままかもしれません。問題のあるバージョンによって書き込まれたデータはデータベースに残ります。新しいAPIフォーマットに依存していたサービスは古いレスポンスを受け取って壊れます。
ホットフィックスによるロールフォワードにも独自のリスクがあります。1つのバグを修正しましたが、ホットフィックスが別の何かを変更している可能性があります。緊急修正で機能した設定値が、通常運用では正しくないかもしれません。ホットフィックスは通常のテストなしで迅速に書かれた可能性があり、それ自体に欠陥が含まれているかもしれません。
だからこそ、復旧後の検証はオプションではありません。それは復旧自体が生み出す問題をキャッチするセーフティネットです。
スモークテストから始める
システムが生きているかどうかを確認する最速の方法はスモークテストです。これはアプリケーションのコア機能が動作することを確認する短いチェックセットです。すべての機能やエッジケースではなく、ユーザーが依存するクリティカルパスのみを確認します。
Webアプリケーションの良いスモークテストには以下が含まれます:
- ユーザーはログインできるか?
- メインダッシュボードを表示できるか?
- フォームを送信したりトランザクションを完了したりできるか?
- アプリケーションログにエラーはないか?
これらのチェックは自動化されるべきです。スモークテストを手動でクリックして実行する必要がある場合、インシデント後に疲れてプレッシャーのかかったチームはそれをスキップします。復旧完了から数分以内にスモークテストが実行され、明確な合格または不合格を返すように自動化しましょう。
例えば、curlを使用したシンプルな自動スモークテストは次のようになります:
#!/bin/bash
# ロールバック後のシンプルなスモークテスト
BASE_URL="https://my-app.example.com"
# ヘルスエンドポイントの確認
if ! curl -f -s -o /dev/null "$BASE_URL/health"; then
echo "FAIL: Health endpoint unreachable"
exit 1
fi
# ログインページが読み込まれるか確認
if ! curl -f -s -o /dev/null "$BASE_URL/login"; then
echo "FAIL: Login page not loading"
exit 1
fi
# クリティカルエンドポイントが200を返すか確認
if ! curl -f -s -o /dev/null "$BASE_URL/api/v1/status"; then
echo "FAIL: API status endpoint failed"
exit 1
fi
echo "PASS: All smoke tests passed"
復旧前後のメトリクスを比較する
スモークテストはアプリケーションが動作していることを教えてくれます。メトリクスはそれが正常に動作しているかどうかを教えてくれます。
インシデント前、インシデント中、復旧後の主要メトリクスを比較してください。重要なメトリクスはアプリケーションに依存しますが、一般的なものには以下が含まれます:
- 1秒あたりのリクエスト数
- エラー率(失敗したリクエストの割合)
- 平均応答時間
- メモリとCPU使用率
- データベースクエリのレイテンシ
復旧後のエラー率がインシデント前よりもまだ高い場合、何かがおかしいです。サービスが適切に再起動しなかったのかもしれません。設定がロールバックされなかったのかもしれません。復旧プロセス自体が新しいボトルネックを導入したのかもしれません。
単一のメトリクスに依存しないでください。低いエラー率でも高いレイテンシと組み合わされると、システムが不健康であることを意味する可能性があります。全体像を見てください。
データベース検証には特別な注意が必要
データベースの復旧は最もトリッキーな部分です。デプロイ前に取得したバックアップにデータベースをロールバックした場合、そのバックアップとロールバックの間に書き込まれたデータはすべて失われます。そのデータにはユーザートランザクション、注文、設定変更が含まれる可能性があります。
以下の点を確認する必要があります:
- 失われたデータはビジネス的に許容できるか?
- ログや他のシステムから重要なデータを復旧できるか?
- 新しいバージョンによって残された孤立レコードで、古いバージョンが処理できないものはないか?
場合によっては、ある程度のデータ損失は許容できるという答えになります。他の場合では、特定のレコードを手動で復元する必要があります。いずれにせよ、何が失われたかを把握し、アクションが必要かどうかを判断する必要があります。
他のシステムとの統合を確認する
アプリケーションは孤立して存在しているわけではありません。復旧後、デプロイ中に他のチームが変更したAPIと古いバージョンが互換性がない可能性があります。またはホットフィックスが監視、ロギング、分析システムに送信されるデータのフォーマットを変更したかもしれません。
接続をテストしてください:
- アプリケーションは外部APIを呼び出せますか?
- それらのAPIはアプリケーションのバージョンが解析できるレスポンスを返しますか?
- ダウンストリームサービスは期待するデータを受信していますか?
復旧後の統合問題は一般的です。なぜならチームはしばしば自分のアプリケーションに集中し、それに依存するサービスや依存されるサービスを忘れるからです。
ユーザーの視点から検証する
ダッシュボードとログはシステムが何をしているかを示します。しかし、ユーザーが何を経験しているかを常に示すわけではありません。ユーザーはエラーログを生成しない空白のページを見るかもしれません。フロントエンドがエラーメッセージを表示しないため、トランザクションが静かに失敗するかもしれません。
可能であれば、復旧後に内部ユーザーに主要機能をテストしてもらってください。または実際のユーザーモニタリングツールを使用して、トランザクション成功率やセッション時間などのメトリクスを確認してください。これらのメトリクスは、インフラストラクチャ監視が見逃す問題を明らかにすることがよくあります。
発見事項を文書化する
検証が完了したら、何が起こったかを書き留めてください。この文書化には2つの目的があります:
- 復旧が成功し、システムが正常に戻ったという証拠を提供します。
- チームが次回のためにデプロイと復旧プロセスを改善するのに役立ちます。
何が問題だったか、復旧に何が含まれていたか、検証中に何を確認したか、発見した問題を含めてください。この記録は、将来同様の問題に直面する他のチームメンバーを助けます。
実用的な検証チェックリスト
以下は復旧後に使用する短いチェックリストです:
次のフローチャートは、各ステップで決定ポイントを持つ検証シーケンスを示しています:
- すべてのクリティカル機能でスモークテスト合格
- エラー率がインシデント前のレベルに戻った
- 応答時間が正常
- リソース使用量(CPU、メモリ、ディスク)が安定
- データベース整合性確認済み、データ損失を文書化
- すべての外部統合が機能している
- ユーザー向けメトリクスが正常な動作を示している
- 発見事項を将来の参考のために文書化
インシデントの本当の終わり
復旧後の検証は形式的なものではありません。インシデント解決を宣言する前の最後の防御線です。これなしでは、後でより大きなインシデントを引き起こす方法でまだ壊れているシステムを正常と呼ぶリスクがあります。
システムが実際に動作していることを確認した瞬間、それがインシデントが本当に終わるときです。それ以前のすべては単なる復旧です。