インフラ変更が失敗したときの復旧オプション:再適用からフェイルオーバーまで
本番インフラに terraform apply を実行した。出力は正常。エラーなし。ところが、モニタリングアラートが鳴り響く——ユーザーがデータベースに接続できない。あなたが行ったセキュリティグループの変更が、誤ってアプリケーション層をブロックしてしまったのだ。
さて、どうする?
この瞬間こそ、復旧計画を持つチームと、必死に最後に正常だった構成を探し始めるチームの分かれ目である。インフラの変更は、アプリケーションのロールバックでは対処できない形で失敗することがある。設定のプッシュが悪いと、コード自体は壊れなくても、接続性、ストレージ、アクセス制御が壊れる可能性がある。復旧には、独自のプレイブックが必要だ。
ここでは、最もシンプルなものから最も複雑なものまで、4つの復旧オプションを見ていこう。それぞれ異なる状況に適しており、実際に必要になる前に理解しておくべきトレードオフが存在する。
旧状態の再適用
最も直接的なアプローチ:インフラを変更前の構成に戻す。
Terraformを使っているなら、以前のステートファイルまたは構成で terraform apply を実行することを意味する。Pulumi、CloudFormation、その他どのInfrastructure-as-Codeツールでも考え方は同じだ。システムに対して、既知の正常なバージョンのインフラ定義を復元するよう指示する。
この方法は、変更が冪等であり、関係するリソースが重要なデータを保持していない場合に有効だ。セキュリティグループルール、コンピュートインスタンスの環境変数、ロードバランサーの設定などを考えてほしい。これらのリソースは、副作用なく元に戻したり再適用したりできる。
以下は、旧状態を再適用するための具体的なコマンドシーケンスである:
# 1. 以前のステートファイルが存在することを確認
ls -la terraform.tfstate.backup
# 2. 以前のステートを復元(現在のステートを上書き)
cp terraform.tfstate.backup terraform.tfstate
# 3. Terraformが元に戻すために行う変更をプレビュー
terraform plan -state=terraform.tfstate
# 4. 旧ステートを適用してインフラを復元
terraform apply -state=terraform.tfstate -auto-approve
注意: 適用する前に、バックアップステートファイルが有効であることを必ず確認すること。
terraform state list -state=terraform.tfstate.backupを実行して、期待するリソースが含まれていることを確認する。
ただし、注意点もある。旧ステートがまだ存在している必要がある。チームが古いステートファイルを削除していたり、インフラプロバイダーがリソースをガベージコレクションしていたりすると、再適用するものが何もない可能性がある。また、このアプローチはステートフルなリソースには不向きだ。古いデータベース設定を再適用したからといって、データが以前の状態に戻るとは限らない。
再適用は高速で、手動介入が最小限で済み、ほとんどのステートレスなインフラ変更に有効だ。しかし、万能な解決策ではない。
スナップショット復元
変更がデータを保持するリソースに影響を与える場合、再適用だけでは不十分だ。データ自体を復元する必要がある。
データベース、ファイルシステム、その他ステートフルなリソースに変更を加える前に、スナップショットを取得しよう。クラウドプロバイダーは、ボリューム、データベース、ストレージバケットに対してこれを提供している。スナップショットは、特定の時点におけるリソースの状態をキャプチャする。
変更が失敗した場合、そのスナップショットから復元する。データベースは変更前の状態に戻り、ファイルシステムは以前の内容に戻る。
このアプローチは再適用よりも負荷が大きい。スナップショットの復元には時間がかかる。その間、リソースは利用不可になる可能性がある。ユーザーはエラーやサービス低下を目にするだろう。しかし、ステートフルなリソースにとって、スナップショット復元はしばしば唯一の信頼できる選択肢となる。
この方法は、影響範囲が1つのリソースまたはコンポーネントに限定されている場合に最も効果的だ。データベーススキーマを変更してアプリケーションが壊れた場合、データベースのスナップショットを復元すればデータ層は修正される。アプリケーションの再起動が必要かもしれないが、データは正常に戻る。
主な欠点:スナップショット取得から失敗した変更までの間に書き込まれたデータは失われる。アプリケーションが継続的に書き込みを行う場合、そのギャップが問題になる。スナップショットのタイミングはそれに応じて計画しよう。
DNSロールバック
時には、最速の復旧はインフラの復元とは全く関係ない。壊れたバージョンからトラフィックを迂回させることにある。
DNSロールバックはトラフィックルーティングレベルで機能する。インフラの変更を元に戻す代わりに、まだ稼働している古いインフラにトラフィックを向け直す。
アプリケーションサーバーの新しいバージョンをデプロイしたとしよう。サーバー自体は問題ないが、設定変更が何かを壊した。古いサーバーは古い設定でまだ稼働している。DNSレコードまたはロードバランサーの設定を更新して、トラフィックを古いサーバーに戻す。
これは高速だ。非常に高速である。DNSの変更は管理された環境内で迅速に伝播し、ロードバランサーの更新はほぼ瞬時に行われる。何かを再構築したり復元したりする必要はない。
しかし、重要な要件がある。古いインフラがまだ存在していなければならない。デプロイプロセスが新しいリソースを作成する際に古いリソースを破棄する場合、DNSロールバックは選択肢にならない。この戦略は、ブルーグリーンデプロイメントやカナリアリリースのように、古いバージョンと新しいバージョンが並行して稼働する場合に自然に機能する。
また、DNSロールバックは根本的な問題を修正するわけではない。壊れたインフラはまだ存在している。後で調査して修正する必要がある。しかし、ユーザーを迅速にオンラインに戻すためには、これに勝る方法はない。
スタンバイ環境へのフェイルオーバー
これは最も複雑な復旧オプションであり、同時にクリティカルなシステムにとって最も信頼性の高い方法でもある。
本番環境をミラーリングするセカンド環境を維持する。これは別のアベイラビリティゾーン、別のリージョン、あるいは別のクラウドプロバイダーでも構わない。スタンバイ環境は、同じインフラ、同じアプリケーションバージョンを実行し、同期されたデータを持つ。
本番環境での変更が失敗し、その影響が広範囲に及ぶ場合、フェイルオーバーを実行する。すべてのトラフィックがスタンバイ環境に移行する。ユーザーは作業を続けられ、本番環境を修正するための時間を稼げる。
フェイルオーバーには、DNS変更、データベースレプリケーション管理、データ同期が伴う。インシデント発生時にこれを理解しようとするのは避けたい。フェイルオーバープロセスは定期的に、理想的には通常業務の一環としてテストする必要がある。
投資は大きい。スタンバイ環境の運用にはコストがかかる。データ同期は複雑さを増す。フェイルオーバープロセスを理解し、プレッシャーの中で実行できる人材が必要だ。
しかし、常に稼働し続けなければならないインフラにとって、フェイルオーバーは最も信頼できる選択肢である。銀行、医療システム、大規模Eコマースプラットフォームがこのアプローチを採用しているのは、ダウンタイムのコストがスタンバイ環境を維持するコストをはるかに上回るからだ。
適切なオプションの選択
各復旧オプションは異なるシナリオに適している:
- 旧状態の再適用: ステートレスな変更、迅速な修正、データリスクが低い場合
- スナップショット復元: ステートフルな変更、単一リソースへの影響、データ整合性が必要な場合
- DNSロールバック: 並行環境、高速復旧、古いインフラがまだ存在する場合
- フェイルオーバー: クリティカルシステム、広範囲な影響、高いアップタイム要件
選択は3つの要因に依存する:行おうとしている変更の種類、潜在的な影響範囲、そしてどれだけ迅速に復旧する必要があるか。
以下のフローチャートは、一般的な障害シナリオを推奨される復旧パスにマッピングする:
次のインフラ変更前の実践的チェックリスト
次の terraform apply や設定変更を実行する前に、このチェックリストを確認しよう:
- この変更に対する復旧オプションを把握しているか?
- 旧ステートファイルはアクセス可能で有効か?
- 変更がステートフルなリソースに影響する場合、スナップショットを取得したか?
- DNSロールバックが必要な場合、古いインフラはまだ稼働しているか?
- 過去1ヶ月以内にフェイルオーバープロセスをテストしたか?
- チームは誰が復旧を実行し、どのように実行するかを把握しているか?
具体的な教訓
インフラ障害からの復旧は、完璧な戦略を1つ持つことではない。行う変更に復旧オプションをマッチングさせることだ。セキュリティグループの変更に完全なフェイルオーバーは必要ない。データベースマイグレーションにはおそらくスナップショットが必要だ。カナリアデプロイメントはDNSロールバックの恩恵を受ける。
必要になる前に、自分の選択肢を知っておこう。復旧方法を決めるタイミングは、変更を行う前であって、アラートが鳴り始めた後ではない。