Terraform - 語法
Terraform語法
官方文檔:https://developer.hashicorp.com/terraform/language
Terraform配置文件
- 配置文件支持兩種格式HCL(HashiCorp Configuration Language)、JSON
- HCL格式后綴名以
.tf結尾,JSON格式后綴名以.tf.json結尾 - HCL格式更加人性化,支持“//”注釋,并且是大多數Terraform文件通常推薦的格式
- JSON格式適用于機器創建,修改和更新,也可以由Terraform操作員完成
- Terraform配置是聲明式的,對其他資源和變量的引用不依賴于它們定義的順序
Provider 插件
- Terraform通過provider管理基礎設施,使用provider與云供應商API 進行交互
- 每個Provider都包含相關的資源和數據源
- providers : https://registry.terraform.io/providers
- provider分類:官方版、認證版、社區版、留檔版(不維護)
聲明Provider
- 每個 Terraform 模塊必須聲明需要哪些Provider,以便 Terraform可以安裝和使用
- 要求在 required_providers 語句塊中聲明對應Provider的源地址、版本
配置Provider
- 關鍵字 provider 自定義Provider名稱
- 配置對應參數,例如 access_key、secret_key、region等
同一個Provider定義多個配置
- 在配置provider通過alias可以為同一個Provider定義多個配置
- 在資源中通過 provider關鍵字 引用
. - 可以支持一個云廠商的多個區域
- 需要有一個默認的provider存在
Resource 資源
在Terraform中,一個具體的資源或者服務稱之為一個resource,
每個特定的resource包含了若干可用于描述對應資源或者服務的屬性字段,通過這些字段來定義一個完整的資源或者服務。
- 通過 resource 關鍵字來定義一個資源塊
- 每個資源塊描述一個或多個基礎對象、計算實例或更高級別的組件,例如網絡、DNS 記錄
- 資源名稱必須以字母或下劃線開頭,并且只能包含字母、數字、下劃線和破折號
- 資源參數引用:
. .
定義一臺ECS實例,需要的參數:可用區、安全組、實例規格、系統盤類型、名稱描述、鏡像、實例名稱、帶寬、交換機、付費類型、賬戶密碼等等
定義一條DNS記錄,需要的參數:域名、主機記錄、類型、值(IP)等
DataSource 數據源
在Terraform中,Data Source 提供的就是一個查詢資源的功能,每個data source實現對一個資源的動態查詢,Data Souce的結果可以認為是動態變量,只有在運行時才能知道變量的值。
- 提供資源的數據,可以通過參數過濾數據并供其他模塊引用
- 使用data塊聲明
- 在data塊中定義需要的屬性
- 如果數據源信息較多,建議單獨放置在一個tf文件中
定義一個系統鏡像數據源,需要的參數:名稱、架構、類型、狀態等
表達式
- https://developer.hashicorp.com/terraform/language/expressions
- 在項目根目錄下執行 terraform console 命令可以進行條件表達式語句的調試
條件表達式
condition ? true_val : false_val
- condition 條件 (返回值true/false)
- true_val 條件為true的值
- false_val 條件為false的值
for表達式
[ for VAR in OBJECT : VAR]
[ for INDEX, VAR in OBJECT: “${INDEX}=${VAR}”]
- 借助for表達式可以對數據進行處理,生成新的數據對象;
- 多用于list、map等數據類型
splat表達式
比用for表達式更簡潔的循環方式
示例
variables.tf
variable "region" {
type = string
description = "define region name"
}
variable "owner" {
type = string
description = "define owner name"
}
variable "environment" {
type = list(string)
description = "define env name"
}
variable "dns_record" {
type = map(string)
description = "define dns name"
}
variable "ecs_spec" {
type = list(map(string))
}
terraform.tfvars
region = "beijing"
owner = ""
environment = ["dev", "test", "pre", "prod"]
dns_record = {
"dev" = "dev.sample.site",
"test" = "test.sample.site",
"pre" = "pre.sample.site",
"prod" = "prod.sample.site"
}
ecs_spec = [{
"name" = "ecs01",
"system" = "linux"
}, {
"name" = "ecs02",
"system" = "windows"
}]
output.tf
output "my_region" {
value = var.region != "" ? var.region : "shanghai"
}
output "my_owner" {
value = var.owner != "" ? var.owner : "anliven"
}
output "my_env1" {
value = var.environment
}
//for循環list對象,輸出新的數據對象
output "my_env2" {
value = [for value in var.environment : "${value}"]
}
//for循環list對象,輸出新的數據對象
output "my_env3" {
value = [for index, value in var.environment : "${index}-${value}"]
}
output "my_dns1" {
value = var.dns_record
}
//for循環map對象,輸出新的數據對象
output "my_dns2" {
value = [for key, value in var.dns_record : "${key} : ${value}"]
}
output "my_ecs1" {
value = var.ecs_spec
}
//splat循環,輸出新的數據對象
output "my_ecs2" {
value = var.ecs_spec[*].name
}
輸出結果
liven@livenan MINGW64 /d/Testing/tf-files/tf-learn-expressions
$ terraform plan
Changes to Outputs:
+ my_dns1 = {
+ dev = "dev.sample.site"
+ pre = "pre.sample.site"
+ prod = "prod.sample.site"
+ test = "test.sample.site"
}
+ my_dns2 = [
+ "dev : dev.sample.site",
+ "pre : pre.sample.site",
+ "prod : prod.sample.site",
+ "test : test.sample.site",
]
+ my_ecs1 = [
+ {
+ name = "ecs01"
+ system = "linux"
},
+ {
+ name = "ecs02"
+ system = "windows"
},
]
+ my_ecs2 = [
+ "ecs01",
+ "ecs02",
]
+ my_env1 = [
+ "dev",
+ "test",
+ "pre",
+ "prod",
]
+ my_env2 = [
+ "dev",
+ "test",
+ "pre",
+ "prod",
]
+ my_env3 = [
+ "0-dev",
+ "1-test",
+ "2-pre",
+ "3-prod",
]
+ my_owner = "anliven"
+ my_region = "beijing"
You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
liven@livenan MINGW64 /d/Testing/tf-files/tf-learn-expressions
$
Module模塊
- https://developer.hashicorp.com/terraform/language/modules
- 通過module可以復用配置代碼,簡化管理和編寫次數,減少開發量和維護量。使資源標準化的同時,提高了代碼整潔性,減少了人為錯誤發生頻率。
- Terraform 模塊是一個或多個.tf 文件集合,可以理解為一個目錄下的tf文件是一個模塊
- 一般嵌套不超過2層,維護可讀性和可維護性
Module語法
- name: 模塊的名稱,在terraform中可以使用模塊名稱進行引用
- source:模塊代碼的路徑,本地或者遠程的倉庫
- version: 版本信息
分類
- 遠程模塊:存儲到根模塊下的.terraform目錄中(修改后,必須get/init)
- 本地模塊:將通過軟連接的方式引用本地的源目錄(修改后,無需操作)
命令
- 使用terraform get 下載模塊
- 使用terraform graph 查看模塊;-module-depth 匯總對象
引用
- 模塊的輸出值,便于其他模塊引用
- 引用方式: module.MODULE_NAME.OUTPUT_NAME
實例化
- 一個模塊可以被多次實例化
- 每個實例定義唯一的名稱,指定相同的 source 來源
行動是絕望的解藥!
歡迎轉載和引用,但請在明顯處保留原文鏈接和原作者信息!
本博客內容多為個人工作與學習的記錄,少數內容來自于網絡并略有修改,已盡力標明原文鏈接和轉載說明。如有冒犯,即刻刪除!
以所舍,求所得,有所獲,方所成。

浙公網安備 33010602011771號