Terraformで「破壊」を御する:ゼロダウンタイムを実現するライフサイクル管理の極意
エンジニア諸君、Terraformの`terraform apply`を実行する際、心臓が止まりそうになったことはないか?特にネットワークインターフェースやデータベース、あるいはロードバランサの再作成を伴う変更において、その一押しがサービス停止を引き起こす引き金になる。
我々SREにとって、IaCは単なる構成管理ではない。「稼働し続けるシステムを、止めることなく進化させるための防壁」だ。今回は、Terraformの`lifecycle`ブロックを使いこなし、リソースの置き換えを「破壊」から「安全な移行」へと昇華させるための実践的テクニックを伝授する。
—
1. `create_before_destroy` の真実:依存関係のジレンマを解消する
Terraformのデフォルト動作は「Destroy(削除)」してから「Create(作成)」だ。しかし、この挙動はロードバランサや静的IPを保持するリソースにおいて、致命的な瞬断を招く。
`create_before_destroy`は、その順序を逆転させ、「新しいリソースを作ってから、古いリソースを捨てる」ことを可能にする。
実践的コード例
resource “aws_lb_target_group” “api_tg” {
name = “api-target-group”
port = 80
protocol = “HTTP”
vpc_id = var.vpc_id
# 変更時にサービス停止を防ぐためのライフサイクル設定
lifecycle {
create_before_destroy = true
}
}
【注意点:依存関係の連鎖】
単にこのオプションを入れるだけでは不十分な場合がある。`create_before_destroy`は、そのリソースを依存先とするリソースすべてに波及する。もし依存ツリーの最上位でこれを使うと、全リソースが新規作成対象となり、クォータ制限(API制限)に引っかかる可能性がある。設計時には、影響範囲をグラフで確認する癖をつけろ。
—
2. 「うっかり」を物理的に遮断する `prevent_destroy`
誤操作による本番環境の全消去を防ぐ最終防衛ラインだ。
resource “aws_db_instance” “master_db” {
# 誤ってterraform destroyを実行しても、このリソースは保護される
lifecycle {
prevent_destroy = true
}
}
現場では、これを「恒久的な保護」として使うのではなく、「破壊的な変更には必ずコードレビューを強制する仕組み」として利用する。破壊が必要な場合は、あえてコードを書き換えてPRを出すというワンクッションが、事故を劇的に減らす。
—
3. 生産性を極限まで高める「エンジニアの武器」
Terraformのコードを書く速度は、ツールの習熟度で決まる。今すぐ導入すべきツールを紹介する。
おすすめプラグイン・設定
- VS Code: HashiCorp Terraform Extension (公式)
- `terraform validate`や`fmt`を保存時に自動実行するよう設定せよ。
- tflint
- クラウド固有の非推奨設定や、セキュリティリスクをコーディング中に指摘してくれる。これなしでIaCを書くのは、地図なしで密林を歩くのと同じだ。
- Terraform Docgen
- READMEに変数や出力を手動で書く時代は終わった。`terraform-docs`を使い、CI/CDパイプラインで自動生成せよ。
キーボードショートカット(極秘)
- `Ctrl + Shift + P` -> “Terraform: Format”: 指が覚えるまで叩け。
- `Ctrl + Click`: 変数やモジュールの定義元へジャンプ。複雑なモジュール構成を追いかける際の必須スキルだ。
—
4. チーム開発で勝つための「構成管理ルール」
チームの生産性を底上げするベストプラクティスは、「DRY原則を過信しないこと」だ。
1. ディレクトリ構成は「責務」で分ける:
`env/prod/vpc`, `env/prod/db` のように、ライフサイクルの異なるリソースは物理的にディレクトリを分ける。これにより、TerraformのStateファイルが巨大化してロックされるリスクを回避できる。
2. `terraform.tfvars` の共有は厳禁:
設定ファイル(JSON/YAML)はCI/CDの環境変数やSecret Managerから注入せよ。手元のファイルは`.gitignore`に含めるのが鉄則だ。
3. モジュール化の誘惑に勝て:
最初から汎用モジュールを作ろうとするな。3回同じ構成を書いてから、初めてモジュール化を検討する。過剰な抽象化は、トラブルシューティングの難易度を跳ね上げる。
実用的な構成例 (ディレクトリ構成)
.
├── modules/ # 再利用可能なモジュール
├── environments/
│ ├── prod/
│ │ ├── backend.tf # S3/DynamoDBバックエンド設定
│ │ ├── main.tf # リソース定義
│ │ └── variables.tf
│ └── dev/
└── README.md # チームへの構築手順の要約
—
最後に:SREとしての矜持
Terraformは単なる「設定ファイル」ではない。インフラの「あるべき姿」を記述した、システムそのものの設計図だ。
`create_before_destroy`を使いこなせば、ダウンタイムは「悪」から「制御可能なイベント」へと変わる。ツールを操るのではなく、ツールを通じて「インフラの安定」という哲学を実装してほしい。
さあ、エディタを開け。君たちのコードで、世界を止めないインフラを構築する時だ。