インフラ変更が失敗したときの段階的な復旧手順
パイプラインが赤くなった。本来2分で終わるはずのTerraform applyが15分経っても完了しない。監視ダッシュボードには5つのリソース作成失敗が表示され、ロードバランサーのヘルスチェックは503を返している。チャットは今のところ静かだが、その静けさが長く続かないことは分かっている。
これはすべてのインフラエンジニアが恐れる瞬間だ。失敗そのものではなく、その後に続く不確実性——最初に何をすべきか?すぐにロールバックすべきか?その場で修正を試みるべきか?本当に正常に戻ったことをどうやって確認するのか?
制御された復旧と混沌とした混乱の違いは、事前に明確な行動手順を持っているかどうかにかかっている。ここでは、インフラ変更が失敗したときに復旧を実行するための実践的な手順を紹介する。
ステップ1: 障害の確認
トラブルの最初の兆候は、ユーザーからの苦情ではなく、パイプラインと監視システムから得られるべきだ。適切に設計されたインフラ変更用のCI/CDパイプラインには、各ステップを検証するチェックポイントが含まれている:リソースは正常に作成されたか?設定は正しいか?サービスは適切に応答しているか?
実際の障害確認は次のようになる:
# Terraform planの出力でエラーを確認
terraform plan -var-file=production.tfvars
# 明確な失敗を示す出力例
# Error: Error creating security group: InvalidGroup.Duplicate: The security group 'web-sg' already exists
# on main.tf line 42, in resource "aws_security_group" "web":
# 42: resource "aws_security_group" "web" {
# 失敗したジョブのパイプラインログを確認
curl -s https://pipeline.internal/api/v1/jobs/12345/logs | tail -50
# ログスニペット例
# [ERROR] Terraform apply failed: Error creating security group: InvalidGroup.Duplicate
# [INFO] Retry attempt 1/3...
# [ERROR] Terraform apply failed: Error creating security group: InvalidGroup.Duplicate
チェックポイントが失敗すると、パイプラインは停止し、何か問題があることを通知する。しかし、復旧モードに飛び込む前に、障害が本物であることを確認しよう。監視アラートはさまざまな理由で発報する:一時的なネットワークの不具合、リトライで解決するタイムアウト、あるいは誤設定されたヘルスチェックによる誤検知など。
確認すべきこと:
- パイプラインログを確認する。エラーは一貫しているか、断続的か?
- 同じ操作を手動でリトライした場合に成功するか確認する。
- 監視アラートが既知の誤検知でないか確認する。
障害が確認されたら、次のステップに進む。一過性の問題であれば、それを記録して次に進む。小さな問題で完全な復旧を開始する必要はない。
ステップ2: 復旧戦略の決定
ここで、事前に作成された復旧計画が役立つ。緊迫した状況で、ロールバックすべきか、以前の状態を適用すべきか、バックアップ環境にフェイルオーバーすべきかを議論している余裕はない。それらの判断は、すでに文書化され、チームで合意されているべきだ。
この判断の鍵となるのは時間だ。ほとんどの復旧計画にはロールバックウィンドウが定義されている:変更後、完全なロールバックが安全な期間のことだ。障害が数分以内に検出された場合、通常は以前の状態にロールバックするのが最善の選択肢だ。インフラがドリフトする時間はなく、依存するリソースが新しい設定に適応している可能性も低い。
次のフローチャートは判断プロセスをまとめたものだ:
しかし、1時間が経過し、変更がすでに他のリソースに伝搬している場合、単純なロールバックは問題を悪化させる可能性がある。他のシステムが新しい設定に依存し始めているかもしれない。その場合、より良い戦略は、以前の状態を前方適用するか、失敗した変更の影響を受けていないスタンバイ環境にフェイルオーバーすることだ。
3つの一般的な復旧戦略:
- 完全ロールバック:Infrastructure as Codeツールを使用して、正確に以前の状態に戻す。
- 状態再適用:他の変更を元に戻さずに、最後に正常だった設定を適用する。
- フェイルオーバー:変更の影響を受けていない別の環境にトラフィックをルーティングする。
判断は、その場の感覚ではなく、復旧計画に従って行うべきだ。
ステップ3: 復旧の実行
戦略が決まったら、文書化されたとおりに正確に実行する。即興の時間ではない。計画に特定のステートファイルでterraform applyを実行すると書いてあれば、そのコマンドを実行する。より速いかもしれないと思っても、別のフラグや新しいバージョンのツールを試してはいけない。
実行中は、すべてのアクションを記録する。時間、コマンド、出力、予期しない動作をメモする。これらのログは事後分析のためだけではない。復旧自体が新たな問題を引き起こした場合に、何が行われたかを追跡するのに役立つ。
戦略がフェイルオーバーを含む場合は、事前に準備したメカニズムを起動する。DNSレコードの更新、ロードバランサーターゲットの切り替え、ルーティング設定の変更などが含まれる可能性がある。正確な手順はインフラによって異なるが、原則は同じだ:直感ではなく計画に従うこと。
ステップ4: 復旧の検証
Terraform applyが成功したからといって、インフラが健全だと想定してはいけない。サーバーがオンラインだからといって、アプリケーションが動作していると想定してはいけない。復旧は、すべてが正常に戻ったことを確認するまで完了しない。
検証とは、複数のレイヤーをチェックすることを意味する:
- リソース状態:インフラリソースが期待通りの設定になっているか?
- サービスヘルス:サービスが実行され、リクエストに応答しているか?
- アプリケーション動作:アプリケーションがコア機能を実行できるか?
- 依存システム:このインフラに依存する下流サービスも健全か?
通常のデプロイメント中にパイプラインが実行するのと同じチェックを実行する。自動化されたスモークテストがあれば実行する。手動検証手順があればそれに従う。目標は、願望ではなく確信を持つことだ。
ステップ5: 結果の共有
検証が完了したら、チームの他のメンバーに伝える。他のエンジニアは、自身の変更をデプロイする前にインフラが安定するのを待っているかもしれない。運用チームは同じアラートを監視し、エスカレーションが必要かどうか迷っているかもしれない。
明確なコミュニケーションには以下を含める:
- 何が問題だったか
- 復旧のために何をしたか
- 復旧が成功したかどうか
- 残存するリスクや観察事項
これにより、重複した変更を防ぎ、混乱を減らす。また、他のチームが必要に応じて計画を調整するのにも役立つ。
実践的な復旧チェックリスト
プレッシャーがかかっているときは、シンプルなチェックリストが集中力を保つのに役立つ。以下はチームに合わせて調整できるものだ:
- 障害が本物であることを確認する(一過性の問題や誤警報ではない)
- ロールバックウィンドウを確認する:変更からどのくらい経過したか?
- 事前に作成された計画から復旧戦略を選択する
- 文書化されたとおりに復旧手順を正確に実行する
- すべてのアクションとその結果を記録する
- インフラ状態、サービスヘルス、アプリケーション動作を検証する
- 結果をチームに共有する
復旧後の本当の作業
インフラは正常に戻った。アラートは解除された。チームはひと息つける。しかし、復旧プロセスが本当に終了するのは、「なぜこれが起こったのか、そして再発を防ぐために何ができるのか」という問いに答えたときだ。
復旧後の評価こそ、プロセスを改善する場だ。パイプラインにデプロイ前のチェックを追加する必要があるかもしれない。復旧計画に抜けていたステップがあるかもしれない。チームに明確なロールバックウィンドウポリシーが必要かもしれない。教訓があれば、それを記録し、計画を更新する。
インフラ変更の失敗は、チームの失敗ではない。それはシステムに改善が必要だというシグナルだ。うまく復旧できるチームは、決して失敗しないチームではない。問題が発生したときに、明確で、練習され、繰り返し可能なプロセスを持っているチームなのだ。