經過前兩天的介紹,我們已經了解 Terraform 的基本運作方式與模組結構。
今天要更進一步,介紹 Terraform 背後使用的語言 —— HCL(HashiCorp Configuration Language),並說明它的特性:宣告式語言(Declarative Language)。
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 能在保持宣告式語意的同時,仍具備足夠的動態彈性。
Terraform 的 HCL(HashiCorp Configuration Language)是由 HashiCorp 自行設計的結構化設定語言,官方文件中指出它的目標是:
讓設定既能被機器解析,又能讓人類閱讀與維護。
(Human readable, machine-friendly configuration language)
HCL 的語法介於 JSON 與 YAML 之間,兼具可讀性與嚴謹的結構特徵。
主要特性如下:
Key-Value 結構
幾乎所有設定都以 key = value
為基本單位,類似於 JSON 的屬性宣告。
區塊式層級結構(Block-based)
使用 {}
表示層級與範圍,例如 resource
、variable
、provider
等。這讓 Terraform 能清楚界定不同資源的範圍與作用域。
豐富的資料型別
支援字串(string)、布林(bool)、整數/浮點數、list、map、object 等多層資料結構。
表達式與函數支援
雖然 HCL 是宣告式語言,但仍可在宣告中進行簡單邏輯運算,例如:
locals {
env = "prod"
disk_size = local.env == "prod" ? 100 : 50
}
HCL 保留了宣告式的可重現性與可讀性,同時提供邏輯彈性,使基礎建設自動化既清晰又靈活,適合多環境、多變數場景。
前面提到,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),能讓設定檔同時具備靈活性與可讀性。
在多層自動化的情境中(例如 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的特性及使用方法熟悉。
謝謝各位的閱讀,我們明天見!