復旧訓練:障害が本番環境に到達する前に失敗を練習すべき理由

数ヶ月前、私が関わっていたチームには、よく整備された復旧計画がありました。ウィキには図解、ステップバイステップの手順、問題発生時の連絡先リストが完備されていました。誰もが準備万端だと思っていました。ところがある火曜日の夕方、データベースマイグレーションが、チェックアウトサービスが依存していたカラムを静かに破損させました。チームはウィキを開き、ロールバック手順に従いましたが、スクリプトが動作しないことに気づきました。最近のインフラ変更でいくつかのリソース名が変更されていたものの、誰も復旧計画を更新していなかったのです。5分で終わるはずのロールバックは、2時間に及ぶ炎上対応に変わりました。

書かれた計画と、プレッシャーの中でそれを実行する能力との間には、現実のギャップがあります。そして、そのギャップを埋める唯一の方法は、練習することです。

書かれた計画の問題点

書かれた復旧計画は有用です。障害シナリオを考えさせ、依存関係を文書化させ、責任を割り当てさせます。しかし、紙の上の計画は仮説に過ぎません。それは、手順がまだ正確であり、スクリプトがまだ動作し、関係者がまだ何をすべきかを知っており、文書が最後に更新されてから何も変わっていないことを前提としています。

実際には、ソフトウェアシステムは絶えず変化します。依存関係はアップグレードされ、設定は変わり、データベーススキーマは進化し、チームメンバーは出入りします。6ヶ月前に完璧だった復旧計画が、今日では完全に機能しなくなっている可能性があります。それを知る唯一の方法は、実際に実行してみることです。

これはチームを信頼していないということではありません。複雑なシステムには目に見えないギャップがあることを認めるということです。新しい環境変数が追加されたためにロールバックスクリプトが失敗するかもしれません。監視ダッシュボードが再設定されたために検証手順に時間がかかりすぎるかもしれません。先週入社したばかりのチームメンバーが適切なデータベース認証情報を持っていないかもしれません。これらのギャップは、実際に計画を実行したときに初めて表面化します。

復旧訓練の実際

復旧訓練とは、安全な環境で実行されるシミュレートされた障害シナリオです。目的はパニックを引き起こすことではありません。目的は、復旧手順が実際に機能するかどうかをテストすることです。いくつかの一般的な形式があります。

ゲームデイは最も構造化された形式です。チームは半日または一日を確保し、複数の障害シナリオを実行します。例えば、重要なサービスを意図的に停止させ、自動フェイルオーバーが期待通りに機能するかを観察します。あるいは、データベースが破損したシナリオをシミュレートし、バックアップからの復旧にかかる時間を計測します。ゲームデイは包括的ですが、かなりの準備と調整が必要です。

障害訓練はより短く、焦点が絞られています。特定のシナリオを1つ選び、1〜2時間で実行します。例えば、最新のデプロイで決済フローにバグが混入したとシミュレートし、チームがロールバックして以前のバージョンが正常であることを確認するまでの時間を計測します。障害訓練はスケジュール調整が容易で、より頻繁に実施できます。

テーブルトップ演習は最も軽い形式です。チームがホワイトボードや共有ドキュメントの周りに集まり、障害シナリオを口頭で進めます。実際のシステムには触れません。これは意思決定とコミュニケーションフローをテストするのに役立ちますが、技術的な手順が実際に機能するかどうかを検証するものではありません。

最も価値のある訓練は、ステージング環境やプレプロダクション環境で実際のシステムに触れるものです。そこに隠れたギャップが潜んでいます。

以下の図は、シミュレーションから計画更新までの復旧訓練のコアループを示しています。

flowchart TD A[Simulate failure in staging] --> B[Execute recovery plan as written] B --> C{Observe outcome} C -->|Plan works| D[Document success conditions] C -->|Plan fails| E[Identify gaps] E --> F[Fix scripts, docs, or access] D --> G[Update recovery plan] F --> G G --> H[Schedule next drill] H --> A

訓練中の失敗に価値がある理由

復旧訓練を合格・不合格の練習と捉えるのは魅力的です。訓練が成功すればチームは気分が良く、失敗すれば恥ずかしい思いをします。しかし、その捉え方は本質を見失っています。

訓練中の失敗は贈り物です。本番環境に到達する前に問題を発見したことを意味します。訓練中にロールバックスクリプトが失敗すれば、修正する時間があります。検証プロセスに時間がかかりすぎれば、最適化できます。チームメンバーがロールバックのトリガー方法を知らなければ、トレーニングできます。これらは本番環境では実際の損害を引き起こしていたであろう問題ですが、今は単なる学習の機会です。

逆もまた真なりです。成功した訓練は誤った自信を与えるかもしれません。シナリオが単純すぎたのかもしれません。訓練だとわかっていたのでチームが特別な注意を払ったのかもしれません。ステージング環境が本番環境とは異なる設定になっているのかもしれません。成功した訓練は、復旧計画が堅牢であることの証明ではありません。特定の条件下で機能したという証拠に過ぎません。

だからこそ、訓練は多様であるべきです。シナリオをローテーションし、タイミングを変え、予期せぬ複雑さを導入します。訓練が現実的であればあるほど、得られるフィードバックはより有用になります。

訓練が技術的ステップ以外に明らかにするもの

復旧訓練は、どの文書も捉えることのできないものを明らかにします。本番環境でロールバックを実行するためのアクセス権を実際に誰が持っているかがわかります。オンコールエンジニアが適切なアラートを十分に迅速に受信できるかどうかが示されます。プレッシャーが高まったときにチーム間のコミュニケーションが明確に保たれるかどうかがテストされます。

私は、ロールバックスクリプトは完璧に動作したものの、承認権限を持つ人を特定するのにチームが20分を費やした訓練を見たことがあります。技術的な手順は正しかったものの、システムが復旧したことを確認するための適切なメトリクスが監視ダッシュボードに表示されなかった訓練も見ました。これらは、訓練を実行して初めて表面化する組織的・プロセス上の問題です。

どのくらいの頻度で訓練すべきか

頻度は、デプロイの頻度と変更のリスクの高さに依存します。1日に複数回デプロイするチームは、少なくとも月に1回は訓練すべきです。週次または隔週でデプロイするチームは、四半期ごとに訓練できます。重要なのは一貫性です。誰も繰り返さない一度きりの訓練は、ほぼ無価値です。2回目の訓練で、最初の訓練からの修正が実際に機能することを検証します。3回目の訓練で、プロセスが体に染み付きます。

各訓練の後、学んだことを文書化し、復旧計画を更新します。不足している手順を追加します。壊れたスクリプトを修正します。適切な人にアクセス権を付与します。訓練のたびに更新される復旧計画は、現実を反映した生きた文書となり、埃をかぶる静的な遺物ではありません。

初めての訓練のためのクイックチェックリスト

これまで復旧訓練を実施したことがない場合は、小さく始めてください。あなたが夜も眠れなくなるようなシナリオを1つ選びます。それは、デプロイの失敗、データベースの破損、サービスの設定ミスかもしれません。次に、このチェックリストを実行します。

  • 安全な環境(本番環境ではなく、ステージングまたはプレプロダクション)を選択する。
  • 成功の定義を決める(例:10分以内にシステムが正常になる)。
  • 役割を割り当てる:誰が訓練を実行し、誰が観察し、誰がメモを取るか。
  • シナリオを実行し、復旧計画に書かれている通りに正確に従う。
  • すべてのステップの時間を計測する。計画が不明瞭または不完全だった箇所を記録する。
  • 訓練後、何が問題だったか、何を変更すべきかを議論する。
  • 復旧計画を更新し、次の訓練をスケジュールする。

最初から完璧を目指さないでください。学習を目指してください。

結論

一度もテストされたことのない復旧計画は、単なる願望に過ぎません。チームが実際に障害から復旧できるかどうかを知る唯一の方法は、安全な環境で障害をシミュレートし、何が起こるかを観察し、壊れたものを修正することです。復旧訓練は、計画が機能することを証明するためのものではありません。本番環境が代わりにギャップを見つける前に、ギャップを発見するためのものです。