iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
自我挑戰組

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

Day2 5Terraform 的宣告式語言與 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)
    使用 {} 表示層級與範圍,例如 resourcevariableprovider 等。這讓 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 專案架構與組態管理
系列文
雲端與資料平台實戰:從抽象概念到落地技術25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言