Terraformの大規模開発を制する:ワークスペースの幻想を捨て、ディレクトリ構造で「堅牢性」を勝ち取る
Terraformを使っているチームが成長フェーズに入ると、必ず直面する壁がある。「環境ごとの差分をどう管理するか」だ。
駆け出しのエンジニアは、まず`terraform workspace`に手を出す。だが、断言しよう。プロダクション環境でワークスペースを使い続けるのは、時限爆弾を抱えて走るようなものだ。
今日は、大規模開発においてインフラの「変更の安全性」と「デプロイ速度」を両立させるための、現場の最終解を共有する。
—
1. ワークスペースの限界とディレクトリ分離の「残酷な真実」
なぜワークスペースは「罠」なのか
Terraformのワークスペースは一見便利だ。単一のコードベースで`terraform workspace select prod`と打つだけで環境を切り替えられる。しかし、これは「状態の孤立」を強制するだけであり、「設定の明示的な分離」ができないという致命的な欠陥がある。
- リスク: 誤操作で`default`環境に`prod`のコードを適用してしまう。
- 管理の難しさ: 環境ごとにリソースの構成(インスタンスサイズや冗長化設定)を変えたい場合、`if/else`がコードに溢れ、読み書きが困難になる。
ディレクトリ分離(Terragrunt流)の優位性
ディレクトリによる分離は、環境ごとに物理的にコードを分ける。一見冗長に見えるが、これが「疎結合」を生む。
- メリット: ある環境の破壊的な変更が、他環境に波及する可能性を物理的にゼロにできる。
- デメリット: コードのDRY(Don’t Repeat Yourself)性が損なわれる。
- 解決策: モジュール化を徹底し、構成定義のみを別ファイル(HCL/JSON)で注入する。
—
2. 実践:プロが選ぶディレクトリ構成
以下は、数千台のリソースを管理する大規模環境で採用すべき標準的なアーキテクチャだ。
.
├── modules/ # 再利用可能なコンポーネント(DRYの源泉)
│ ├── vpc/
│ └── eks/
├── environments/ # 環境ごとの定義(ここが境界線)
│ ├── stg/
│ │ ├── main.tf # モジュールを呼び出すだけ
│ │ └── variables.tf
│ └── prod/
│ └── main.tf
└── terragrunt.hcl # 【重要】DRY化のためのオーケストレーター
プロの極意: `main.tf`にはロジックを書くな。変数を渡してモジュールを呼び出すだけの「ラッパー」に徹する。これが変更時の認知負荷を下げる鍵だ。
—
3. 開発スピードを加速させる「極限のツールセット」
手作業でTerraformを回すのは、もはや時代遅れだ。
必須プラグイン(VS Code)
1. HashiCorp Terraform: 公式。文法チェックとシンタックスハイライト。
2. Terraform Doc: README.mdを自動生成する。これがチームのドキュメント負債を解消する。
3. TFLint: 最重要。 クラウドプロバイダーの推奨設定や非推奨オプションを静的解析で弾く。これがないコードは、レビューを通すべきではない。
開発を劇的に速くするショートカット
- `terraform fmt -recursive`: 保存時に自動実行させる設定(`.vscode/settings.json`)を全員で共有せよ。
- `terraform plan -out=tfplan`: プラン結果をバイナリ保存し、`terraform apply tfplan`で適用する。これにより、プランと適用の間の「ズレ」を完全に排除できる。
—
4. チーム開発で役立つ「設定共有ルール」
チームの生産性は「標準化」で決まる。`.vscode/settings.json`をリポジトリルートに含め、以下を全メンバーに強制せよ。
{
“terraform.languageServer”: {
“enabled”: true,
“args”: [“-c”, “terraform-ls serve”]
},
“editor.formatOnSave”: true,
“[terraform]”: {
“editor.defaultFormatter”: “hashicorp.terraform”
}
}
—
5. 現場で震えるほど役立つ「DRYの極意」
環境間で共通の設定を管理する場合、HCLで頑張りすぎないこと。JSON/YAMLで設定値を定義し、`jsondecode`で読み込むのが最も堅牢だ。
config.json (環境依存の設定):
{
“instance_type”: “m5.large”,
“min_size”: 3
}
main.tf (スマートな読み込み):
locals {
# ファイルを読み込み、モジュールへ渡す
config = jsondecode(file(“${path.module}/config.json”))
}
module “app” {
source = “../../modules/app”
instance_type = local.config.instance_type
min_size = local.config.min_size
}
—
結論:コードは「読みやすさ」のために存在する
Terraformのコードは、書く時間よりも「読む時間」の方が圧倒的に長い。
ワークスペースの複雑なロジックを解読する時間を費やすより、ディレクトリを分け、モジュールを整理し、静的解析ツールでガードレールを敷く。
この設計思想こそが、インフラを「自動化された資産」に変える唯一の道だ。
さあ、今すぐ不要なワークスペースを削除し、ディレクトリ構造の再設計に取り掛かってほしい。あなたのチームのデプロイ成功率は、明日から劇的に向上するはずだ。