災害を「計算可能」にせよ:TerraformによるゼロダウンタイムDRの極意
多くのエンジニアが「DR(災害復旧)戦略」を語る際、それは単なる手順書に過ぎないことが多い。しかし、真のSREにとってDRとは「コード化された期待値」である。
リージョンが死ぬ時、管理画面をポチポチ叩くのは敗北を意味する。本稿では、Terraformを単なるリソース構築ツールとしてではなく、「リージョン間状態遷移エンジン」として運用するための、現場で培った極限の設計思想を共有する。
—
1. 状態管理の神髄:State分割は「疎結合」の命
マルチリージョン構築において、最大のアンチパターンは巨大な単一Stateファイルの保持だ。Stateが肥大化すれば、ロックの競合やAPI呼び出しのレイテンシで、緊急時に「Applyが通らない」という悪夢を見る。
推奨構成:階層型モジュールとリージョン別ステート
TerraformのWorkspacesは便利だが、DRという極限状況下では依存関係が可視化しにくい。以下のディレクトリ構造を強く推奨する。
.
├── modules/ # インフラの共通定義(VPC, EKS, RDS等)
├── regions/
│ ├── ap-northeast-1/ # プライマリ環境
│ │ ├── terraform.tfvars
│ │ └── main.tf
│ └── us-east-1/ # セカンダリ(スタンバイ)環境
│ ├── terraform.tfvars
│ └── main.tf
これにより、リージョン間でリソースの依存関係を完全に分離する。DR発動時のアクションは、スタンバイ側のStateを独立してApplyするだけで完結させる。 これこそが冪等性を担保する最短ルートだ。
—
2. 変数設計の極致:動的マッピングによる抽象化
リージョン切り替えにおいて、AMI IDやRDSスナップショットのARNをベタ書きするのは愚行だ。これらを `locals` と `map` を用いて抽象化せよ。
modules/compute/variables.tf
variable “region_map” {
description = “リージョンごとの最適化パラメータ”
type = map(object({
ami_id = string
instance_type = string
}))
default = {
“ap-northeast-1” = { ami_id = “ami-0123456789”, instance_type = “c6g.large” }
“us-east-1” = { ami_id = “ami-9876543210”, instance_type = “c6g.large” }
}
}
呼び出し側
locals {
current_config = var.region_map[var.aws_region]
}
この設計により、DR発動時は `var.aws_region` を切り替えるだけで、全ての依存リソースが整合性を保ったまま再構築される。
—
3. クロスリージョンレプリケーションのIaC化
DRの核心は「データ」だ。RDSのクロスリージョンリードレプリカやS3のクロスリージョンレプリケーション(CRR)をTerraformで管理する場合、以下のポイントに注意せよ。
1. プロバイダのエイリアス活用: `provider` ブロックを複数定義し、リソースごとに明示的に割り当てる。
2. KMSキーのリージョン間共有: 暗号化されたデータは、コピー先リージョンで復号できなければゴミ同然だ。KMSのマルチリージョンキー(Multi-Region Keys)を使用し、IaCで権限を事前配布せよ。
DR用レプリカ作成の肝
resource “aws_rds_cluster_instance” “replica” {
provider = aws.secondary # セカンダリリージョンのプロバイダ
cluster_identifier = aws_rds_cluster.primary.id
# … 省略
}
—
4. 緊急フェイルオーバーの自動化:API/CLI連携
Terraform単体でDRを完結させるのは危険だ。「Terraformで環境を維持し、Go/Pythonで切り替えを制御する」のがプロの現場だ。
独自自動化スクリプトの勘所
1. Stateチェック: `terraform plan -detailed-exitcode` を実行し、環境のドリフト(乖離)を常に監視する。
2. DNSフェイルオーバー: Route53のヘルスチェックと連動させる。Terraformで「スタンバイ環境の正常性確認用エンドポイント」を定義し、それが倒れたら自動でトラフィックを切り替える構成を組む。
3. APIによるキック: AWS SDK (Boto3等) を使い、スタンバイ環境のインスタンス起動・RDSの昇格(Promote)をシリアルに実行するラッパーを書く。
—
5. エキスパートの警告:パフォーマンスとメモリ消費
Terraformはリソース数が増えるとメモリを驚くほど消費する。特に `tfstate` のパース処理は、大規模環境では数GBのメモリを食いつぶすこともある。
- ハック: `target` オプションは最終手段。依存関係が複雑な状態で `target` を使うと、Stateの整合性が崩壊し、復旧不可能になる。
- 高速化: `parallelism` パラメータを調整せよ。デフォルトの `10` は保守的すぎる。環境に余裕があるなら `50-100` に引き上げることで、DR時の再構築速度を飛躍的に短縮できる。
—
結論:DRは「設計」で勝ち、「実行」で勝つ
DR戦略において、Terraformは単なる「設定ファイル」ではない。それは、「どのような危機的状況においても、計算資源を特定の状態に固定するためのアルゴリズム」だ。
環境を小さく保ち、依存関係を極限まで疎結合にし、いざという時にCLIで迷わず叩けるようにしておく。今日から、君のコードを「災害に強い知性」へと進化させよう。
コードは嘘をつかない。書いた通りにしか動かない。だからこそ、最高の結果が出るまで磨き続けろ。