iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
DevOps

30 天 Terraform 學習筆記:從零開始的 IaC 實戰系列 第 21

Day 21 - Terraform Dynamic Blocks 與複雜配置

  • 分享至 

  • xImage
  •  

昨天我們聊到迴圈與條件邏輯,學會了怎麼透過 countfor_each 和條件表達式,讓 Terraform 能一次產生一組資源,或根據環境自動決定要不要建立。

這些技巧解決了「我要建立多個資源」的問題。
但在實際專案裡,我們常常遇到另一種情況:不是「很多個資源」,而是「一個資源裡面有一堆重複的子設定」。
舉個例子:

  • 在 GCP,建立一條 防火牆規則,可能需要同時允許 80、443、8080 這三個 port。
  • 在 AWS,設定 安全群組,一個 ingress 規則要開放多個 CIDR。
  • 或是設定 IAM Policy,同時綁定多個角色或帳號。

這些子設定如果全部手動寫,程式碼馬上就變得很長,幾十行、上百行都是同樣的結構,只是數字或名稱不同。別說改起來麻煩,光是看就頭暈。這時候,Terraform 就幫我們準備了一個好用的工具:Dynamic Blocks

Dynamic Block:讓子設定也能「動態生成」

Dynamic Block 的概念很簡單:
就像昨天的 for_each 可以幫你產生多個資源一樣,Dynamic Block 可以在 資源內部,對子區塊再做一次迴圈。

想像一下,你要建立一個防火牆規則,要開放三個 port:80、443、8080。
如果用傳統寫法,你可能要寫三段 allow 區塊。但有了 Dynamic Block,就能這樣寫:

variable "allowed_ports" {
  default = [80, 443, 8080]
}

resource "google_compute_firewall" "example" {
  name    = "example-firewall"
  network = "default"

  dynamic "allow" {
    for_each = var.allowed_ports
    content {
      protocol = "tcp"
      ports    = [allow.value]
    }
  }
}

Terraform 在 apply 的時候,會自動展開成三個 allow 區塊。

這樣一來,我們的程式碼只有幾行,但效果是一樣的。更重要的是,未來只要改變 allowed_ports 變數,規則就會自動調整,完全不用手動複製貼上。

搭配 Map:處理更複雜的規則

上面例子只是同一種協定(TCP)的多個 port,如果要進一步控制不同的協定怎麼辦?
例如:我要同時允許 TCP 80/443,還要允許 UDP 53。這時候用 Map 搭配 Dynamic Block,就能一次搞定:

variable "rules" {
  default = {
    tcp = [80, 443]
    udp = [53]
  }
}

resource "google_compute_firewall" "example" {
  name    = "example-firewall"
  network = "default"

  dynamic "allow" {
    for_each = var.rules
    content {
      protocol = allow.key
      ports    = allow.value
    }
  }
}

這樣寫展開後 Terraform 就會自動生成:

  • 一條 TCP 規則開 80、443
  • 一條 UDP 規則開 53

這樣比原本要手動寫很多段規則來得更乾淨又直覺。

Dynamic Block + 條件判斷

Dynamic Block 也能和昨天學到的條件判斷結合。
舉個例子:在 production 環境才允許外部存取,其他環境只允許內部。

dynamic "allow" {
  for_each = var.env == "prod" ? ["0.0.0.0/0"] : ["10.0.0.0/8"]
  content {
    protocol = "tcp"
    ports    = ["443"]
  }
}

這樣 dev/test 環境就只允許內部網段,production 才開放給外部。完全不用再維護多份不同的防火牆設定檔,一個程式碼就能搞定。

Dynamic Block 是一個很好用的工具,特別是在面對需要重複子設定的情境時,例如防火牆規則、IAM 綁定,甚至一些安全性設定。這些地方往往結構都很類似,如果單純用複製貼上會顯得冗長又難維護,用 Dynamic Block 就能把重複的部分抽象化,讓程式碼更乾淨。

但它也不是什麼情境都適合使用。如果只是一兩個設定,直接寫死其實會更直觀,也能讓後續閱讀程式碼的人更快理解。Dynamic Block 的價值主要還是在於「減少重複、提升可維護性」,而不是炫技或刻意追求動態化!

總結一下

今天我們把焦點放在 Dynamic Blocks,學會了:

  • 如何在資源內部,用迴圈展開多個子設定。
  • 搭配 list / map,可以讓整體更彈性、乾淨。
  • 可以結合條件式,根據不同環境自動切換規則。
  • 適合用在防火牆、安全群組、IAM 這種「重複子區塊」的場景。

不用每個地方都刻意套用,但在遇到需要高度重複的設定時,它會讓整份配置既乾淨又有彈性。這幾天我們一路從 countfor_each 到條件式,再到今天的 Dynamic Block,其實都是在逐步累積「程式化配置」的能力。

明天要分享的主題則會換個角度,來看看 Functions 與 Local Values,它們能幫助我們在字串、列表、映射的處理上更靈活~


上一篇
Day 20 - Terraform 迴圈與條件邏輯:for_each、count、條件表達式
系列文
30 天 Terraform 學習筆記:從零開始的 IaC 實戰21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言