こんにちは。クラウドインフラの世界へようこそ。
Terraformを触り始めると、誰もが一度は「同じようなリソースを何十個も書くのが面倒だ」「ネストされた複雑な設定をどうやってスマートに管理すればいいんだ?」という壁にぶつかります。
今日は、初心者の方が「Terraformの真の力」を体感し、コードを劇的に美しく進化させるための「for_each」と「dynamicブロック」の奥義を伝授します。これらを使いこなせば、もう手作業のコピペで消耗することはありません。
—
1. Terraformとは何か:インフラの「設計図」をコード化する
Terraformは、AWSやGCPといったクラウド環境を「コード(HCLという言語)」で記述し、自動で構築・管理するツールです。
なぜ重要か?:手作業でポチポチ画面を操作すると、必ず「設定ミス」や「環境の差異」が生まれます。コード化しておけば、いつでも同じ環境を再現でき、変更履歴も残る。これが「IaC(Infrastructure as Code)」の神髄です。
インストールと最初のセットアップ
まずは手元で動かしてみましょう。
1. [公式ドキュメント](https://developer.hashicorp.com/terraform/downloads)からバイナリをダウンロードしてパスを通す。
2. ターミナルで `terraform -version` と打って反応があればOKです。
—
2. for_eachで「反復の呪縛」を解く
リソースを複数作成する場合、初心者は `count` を使いがちですが、実務では `for_each` を使うのがプロの流儀です。
なぜか?:`count` はインデックス(0, 1, 2…)で管理するため、途中のリソースを削除すると全リソースの番号がズレてしまい、意図しない破壊(再作成)を招くリスクがあるからです。
実践:map形式で定義する
variable “subnet_configs” {
type = map(string)
default = {
web-a = “10.0.1.0/24”
web-b = “10.0.2.0/24”
}
}
resource “aws_subnet” “main” {
# mapをループして一つずつリソースを作成
for_each = var.subnet_configs
vpc_id = aws_vpc.main.id
cidr_block = each.value # 値(CIDR)
tags = { Name = each.key } # キー(名前)
}
こうすることで、`subnet_configs` に要素を追加するだけで、コードを一切汚さずにリソースを拡張できます。
—
3. dynamicブロックで「ネストの深淵」を制御する
セキュリティグループのルールや、複雑な監視設定など、「リソース内に同じ構造のブロックを複数書く」場面は非常に多いです。ここで `dynamic` ブロックが真価を発揮します。
悪い例(コピペ地獄)
ingress { from_port = 80 … }
ingress { from_port = 443 … }
これを何十個も書くのは悪夢です
良い例(dynamicブロック)
variable “ingress_rules” {
type = list(object({ port = number, proto = string }))
default = [
{ port = 80, proto = “tcp” },
{ port = 443, proto = “tcp” }
]
}
resource “aws_security_group” “web” {
# リストの中身を動的に展開
dynamic “ingress” {
for_each = var.ingress_rules
content {
from_port = ingress.value.port
to_port = ingress.value.port
protocol = ingress.value.proto
cidr_blocks = [“0.0.0.0/0”]
}
}
}
ここがポイント: `dynamic` は単なる自動化ではなく、設定値(データ)とロジック(コード)を完全に分離するための設計思想です。
—
4. 現場で震えるほど役立つ「裏技」:ネストしたJSONの処理
実務では、外部のJSONファイルから設定を読み込むことがよくあります。`jsondecode()` 関数と `flatten` 関数を組み合わせるのが、複雑な構成を攻略する唯一の正解です。
JSONを読み込んでループさせる魔法
locals {
config = jsondecode(file(“${path.module}/config.json”))
}
複雑なネストを平坦化してfor_eachに渡す
resource “example_resource” “test” {
for_each = { for item in local.config.items : item.name => item }
name = each.value.name
}
—
最後に:エンジニアとして成長するために
ここまで学んだあなたなら、もうTerraformの基礎は卒業です。
最後に一つだけアドバイスを。「コードが複雑になりすぎたら、それは設計を見直すサイン」です。`for_each` や `dynamic` は強力ですが、やりすぎると「何が作られるか一目で分からないコード」になります。常に「他のエンジニアが読んだ時に直感的に理解できるか?」を自問自答してください。
これができるようになった時、あなたは単なる「作業者」から「クラウドアーキテクト」への第一歩を踏み出したことになります。
さあ、エディタを開いて、あなたのインフラを魔法のように自動化してみましょう。応援しています!