iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
自我挑戰組

雲端與資料平台實戰:從抽象概念到落地技術系列 第 25 篇

Day25 Terraform 的宣告式語言與 HCL 函數運用

  • 分享至 

  • xImage
  •  

經過前兩天的介紹,我們已經了解 Terraform 的基本運作方式與模組結構。
今天要更進一步,介紹 Terraform 背後使用的語言 —— HCL(HashiCorp Configuration Language),並說明它的特性:宣告式語言(Declarative Language)。


Terraform的宣告式語言特性

Terraform 屬於宣告式語言,也就是說:

我們描述「想要的結果」,而不是一步步指示「要怎麼做」。

例如:

resource "google_compute_instance" "example" {
  name         = "vm-example"
  machine_type = "e2-medium"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-12"
    }
  }

  network_interface {
    network = "default"
  }
}

這段設定並沒有告訴 Terraform「如何」建立 VM,只是描述「希望有一台這樣設定的 VM」。
Terraform 會根據狀態差異(state diff)自動產生執行步驟。
這就是宣告式語言的核心精神:描述狀態,而非執行步驟。


宣告式語言的類比與程式語言的差異

在上一段我們提到,宣告式語言的核心在於描述狀態,而非執行步驟。
這與一般程式語言(命令式語言)的邏輯方向相反。命令式語言強調流程控制,例如 if、for、while 等結構;而宣告式語言專注在結果描述,讓執行引擎自行推導出「如何達成」。

以 Terraform 為例,我們不會撰寫建立 VM 的步驟(如建立網路、掛載磁碟、啟動服務),而是直接描述「希望存在一個 VM,具備這些屬性」。
Terraform 會根據目前狀態(state)與目標設定(desired state)差異,自動生成必要操作步驟。

類似概念也出現在其他工具:

語言/工具 主要用途 宣告重點 邏輯來源
Helm YAML 應用部署配置 結構與參數描述 由 tpl 模板語法處理邏輯(Go Template)
HTML 頁面結構描述 呈現與標記 行為邏輯由 JavaScript 控制
HCL (Terraform) 基礎建設描述 狀態與屬性宣告 由 locals 與內建函數支援邏輯

可以看出這些語言都屬於「結構描述語言(structured declaration language)」,目的是讓使用者描述想要的狀態或結構,由工具自行負責「怎麼做」。
其中 HCL 位於中間層 —— 比 Helm YAML 更有邏輯性,但又不像 JavaScript 那樣具備完整流程控制。
這讓 Terraform 能在保持宣告式語意的同時,仍具備足夠的動態彈性。


HCL 的結構特性與設計哲學

Terraform 的 HCL(HashiCorp Configuration Language)是由 HashiCorp 自行設計的結構化設定語言,官方文件中指出它的目標是:

讓設定既能被機器解析,又能讓人類閱讀與維護。
(Human readable, machine-friendly configuration language)

HCL 的語法介於 JSON 與 YAML 之間,兼具可讀性與嚴謹的結構特徵。
主要特性如下:

  1. Key-Value 結構
    幾乎所有設定都以 key = value 為基本單位,類似於 JSON 的屬性宣告。

  2. 區塊式層級結構(Block-based)
    使用 {} 表示層級與範圍,例如 resource、variable、provider 等。這讓 Terraform 能清楚界定不同資源的範圍與作用域。

  3. 豐富的資料型別
    支援字串(string)、布林(bool)、整數/浮點數、list、map、object 等多層資料結構。

  4. 表達式與函數支援
    雖然 HCL 是宣告式語言,但仍可在宣告中進行簡單邏輯運算,例如:

    locals {
      env       = "prod"
      disk_size = local.env == "prod" ? 100 : 50
    }
    

HCL 保留了宣告式的可重現性與可讀性,同時提供邏輯彈性,使基礎建設自動化既清晰又靈活,適合多環境、多變數場景。


locals 與函數運用

前面提到,HCL 雖然是宣告式語言,但仍保留一定的邏輯彈性,能在設定中進行動態運算。
這個能力主要透過 locals 區塊 與 內建函數(functions) 來實現。

在實務上,我們常用 locals 來集中管理共用邏輯或運算結果,讓設定更有一致性,也避免在多處重複定義相同變數。以下是幾個常見的應用場景。


範例一:字串處理與變數引用
locals {
  region = "asia-east1"
  zone   = "${local.region}-a"
}

output "zone" {
  value = local.zone
}

Terraform 會輸出 asia-east1-a。
${} 是 HCL 的表達式語法,用來在設定中引用變數或進行字串組合。
在這裡,我們透過 locals 將「可重複邏輯」集中定義,減少後續重複輸入。


範例二:條件運算與動態設定
locals {
  env       = "prod"
  prefix    = "app-${local.env}"
  disk_size = local.env == "prod" ? 100 : 50
}

這裡透過三元運算子 condition ? true_value : false_value 動態決定數值。
如果是 prod 環境,就使用 100GB 的磁碟;否則使用 50GB。
這種寫法常用於多環境部署(例如 dev / staging / prod),能讓設定檔同時具備靈活性與可讀性。


範例三:整合 Helm YAML 與 Terraform,建立唯一來源設定

在多層自動化的情境中(例如 CI/CD pipeline),我們希望 Helm 與 Terraform 共享同一份設定來源,避免重複維護與設定不一致的風險。
透過 file() 與 yamldecode() 函數,可以將 YAML 檔案解析成 Terraform 可用的變數:

locals {
  values       = yamldecode(file("${path.module}/values.yaml"))
  machine_type = local.values.machine_type
}

假設 values.yaml 內容如下:

machine_type: e2-standard-2

Terraform 會自動解析這份 YAML,並將 machine_type 套用到資源宣告中:

resource "google_compute_instance" "example" {
  name         = "vm-${local.machine_type}"
  machine_type = local.machine_type
}

這樣 Helm 設定檔成為 唯一來源,Terraform 自動使用,確保跨層一致性與可重現性。

locals 區塊是 Terraform 中非常實用的工具:它讓宣告式設定具備「邏輯能力」,同時維持語法清晰與可重現性,支援多環境、多變數、多層整合需求。


常用的內建函數

Terraform 提供了許多實用的 內建函數(built-in functions),可以在 locals、變數處理或資源設定中使用,增加設定的彈性與可讀性。

類別 函數 說明
字串 join(), split(), replace() 字串拼接、切割、取代
型別轉換 tostring(), tonumber(), tolist() 不同資料型態轉換
檔案 file(), yamldecode(), jsondecode() 讀取與解析外部檔案
邏輯 contains(), length(), merge() 條件判斷與集合運算

例如前面範例中,我們使用了 file() 與 yamldecode() 解析 Helm YAML,作為 Terraform 變數的唯一來源。這種做法在多環境部署或 CI/CD 流程中非常實用,能確保設定一致性與可重現性。

更完整的函數列表與使用方式,可以參考官方文件:Terraform Functions


小結

經過前三天的學習,我們已從 Terraform 的基礎概念一路延伸到 HCL 語法與函數運用,建立了完整的 Terraform 思路,回顧這三天的內容:

1️⃣ 基礎概念與 HCL 撰寫
我們從 Terraform 的基礎開始,學會用 HCL 描述基礎建設設定,理解 .tf 檔案的 Block 結構與語法規範,並掌握查詢 Provider 文件的方法。透過 terraform init → plan → apply 的操作循環,體驗了從設定檔到實際資源建立的完整流程,也對 Terraform 的宣告式特性有了直觀理解。

2️⃣ 檔案、目錄與狀態管理
學習了 Terraform 如何讀取多個檔案,以及如何透過目錄與模組化設計管理多環境專案。同時理解本地與遠端 State 的差異,掌握多人協作與多環境部署的最佳實務。期望透過今天的內容,大家能熟悉 Terraform 模組化與目錄管理的實務操作,為自動化部署打下穩固基礎。

3️⃣ 宣告式語言與函數應用
今天回顧了宣告式語言的核心:Terraform 描述的是「想要的狀態」,而不是操作步驟。透過 locals 與內建函數,我們可以在設定中加入動態彈性,依環境條件設定參數,甚至將 Helm YAML 作為唯一來源使用,實現跨層一致性與自動化。這三天的學習引導我們從單一 .tf 檔理解到多環境、自動化與跨工具整合的完整思路。

明天將進一步探索資料平台中的 Terraform 配置,並與 Helm、GitLab 協作設計參數策略,實現更完整的自動化部署。

希望這三天的分享,讓各位對terrarom的特性及使用方法熟悉。

謝謝各位的閱讀,我們明天見!


上一篇
Day24 Terraform 專案架構與組態管理
下一篇
Day26 參數的邊界:Terraform、GitLab、Helm 的治理平衡
系列文
雲端與資料平台實戰:從抽象概念到落地技術 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言