Variable 介紹
概述
前文中的示例一直在硬編碼資源參數值,但如果你想參數化配置或者標準化代碼,并在 Terraform 工作流的 apply 階段自定義資源屬性怎么辦?這正是本文要講的變量的用武之地。
變量可以讓你參數化在資源之間共享的值,除此之外,使用變量還具有以下好處:
增加通用性
輸入變量作為參數提供給 Terraform 使用,將源代碼和屬性賦值分離,可以實現對同一份 Terraform 配置的輕松定制和共享,而無需更改源代碼。
提高靈活性
定義變量后,在運行時(apply)有多種方法可以為屬性自定義設置其值,包括環境變量、CLI 選項和鍵值對文件。在如下的示例中,名稱、描述和網段都是硬編碼的。你可以將這些屬性中的任何一個聲明為變量,并在運行時指定具體的值。
resource "alicloud_vpc" "my_vpc" {
vpc_name = "main-vpc"
cidr_block = "10.0.0.0/16"
description = "my first vpc netrowk"
}
變量的語法
接下來讓我們探討如何聲明輸入變量。
變量必須在 variable 塊中聲明。建議將所有的變量聲明保存在一個名為 variables.tf 的文件中。
關鍵字 variable 旁邊的標簽為變量名稱。變量名稱有兩個設置規則:
變量名在模塊內必須唯一
在當前模塊中聲明的變量,名稱必須保持唯一性,當然子模塊中聲明的變量和主模塊中聲明的變量不會沖突。
變量名不能是關鍵字
變量名不能是 Terraform 預留的關鍵字,比如所有的元參數 count,for_each 等
變量沒有必選的參數,因此變量塊可以為空,Terraform 可以根據變量值自動推斷類型和默認值。
type
type 參數指定了變量接受的值的類型。Terraform 支持以下基本變量類型:
bool,用于二進制值,如 true 或 false(不帶引號)
number,用于數值變量
string,用于字符序列
default
default 是變量的另一個元參數,用于給屬性分配默認值。
要訪問模塊內聲明的變量值,可以使用表達式 var.
。在如下的示例中,變量 vpc_cidr_block 在資源塊中格式化為 var.vpc_cidr_block,并被分配給 cidr_block 參數,創建資源時使用引號中的默認值。
resource "alicloud_vpc" "my_vpc" {
vpc_name = "main-vpc"
cidr_block = var.vpc_cidr_block
description = ""
}
variable "vpc_cidr_block" {
default = "10.0.0.0/16"
}
變量塊中的變量名必須與資源塊中的引用相匹配。默認值可以通過分配值在環境變量或 .tfvars 文件或 -var 選項中被覆蓋,如:
# 通過 CLI -var 選項覆蓋變量默認值
$ terraform plan -var vpc_cidr_block="172.16.0.0/16"
description
description 用于記錄變量的用途。當變量沒有定義默認值時,描述將在 plan 或者 apply 階段顯示:
description 字符串通常包含在文檔中,應當解釋變量的用途和預期值。因此應從用戶使用視角而非維護者的角度去編寫。維護者可以使用注釋,而非直接寫到 description 中。
sensitive
sensitive 是一個變量參數,顧名思義,用于保護敏感信息不會顯示在命令輸出或日志文件中。敏感值的可接受值為true。當設置為true時,變量的值在 terraform plan 或terraform apply 的輸出中標記為敏感。
當處理如數據庫憑證或 AccessKey 或者登錄密碼等敏感信息時,此參數非常有用,將變量標記為敏感將消除意外暴露機密信息的風險。
在此示例中,變量 vpc_cidr_block 被標記為敏感。資源 my-vpc 使用了變量 vpc_cidr_block,運行 terraform plan 或 apply 時,值沒有被顯示:
$ terraform plan
Terraform will perform the following actions:
# alicloud_vpc.my-vpc will be created
+ resource "alicloud_vpc" "my-vpc" {
+ cidr_block = (sensitive value)
+ create_time = (known after apply)
+ id = (known after apply)
+ status = (known after apply)
+ user_cidrs = (known after apply)
+ vpc_name = "main-vpc"
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
validation
驗證塊包含一個條件參數,用于指定驗證規則。你可以通過在變量塊中包含驗證子塊來驗證賦給變量的值。
在如下示例中,length 和 substr 用作條件參數,驗證 vpc_name 的值是否長度超過 4 并且是否以 tf- 為開頭:
variable "vpc_name" {
validation {
condition = length(var.vpc_name) > 4 && substr(var.vpc_name, 0, 3) == "tf-"
error_message = "The vpc name must start with 'tf-' and be longer than 4 characters."
}
}
當執行 terraform plan 并且輸入 vpc_name 值為 my-vpc 時,將會觸發規則校驗拋出具體的錯誤信息:
變量的設置方式
在運行時有多種設置變量值的方法:
# .tfvars 文件(推薦)
$ terraform apply -var-file my-vars.tfvars
# CLI 選項
$ terraform apply -var vpc_cidr_block=“172.16.0.0/16”
# 環境變量
$ export TF_VAR_vpc_dicr_block=“172.16.0.0/16”
$ terraform apply
# 默認的變量文件 terraform.tfvars
$ terraform apply
首先,你可以使用 .tfvars 文件快速切換和版本變量集;你也可以使用 CLI 選項,在運行簡單配置文件的快速驗證時非常有用;環境變量在腳本和流水線中非常有用。如果通過 description 的方法沒有設置所需變量,可以使用 CLI 提示。
當需要輸入許多變量定義,尤其是涉及到復雜類型的變量時,在 CLI 選項中設置變量值將會比較困難。相反,可以在擴展名為 .tfvars 或 .tfvars.json 的文件中以 K-V 的方式指定變量值,然后在運行 terraform plan 或者 apply 命令是通過 -var-file 選項指定參數集:
$ terraform plan -var-file my-vars.tfvars
擴展名為 .tfvars 或 .tfvars.json 的文件中的變量定義遵循與 HCL 相同的語法,但僅包含對變量名的賦值。值得注意的是,只要變量文件準確地命名為terraform.tfvars、terraform.tfvars.json、.auto.tfvars或.auto.tfvars.json,Terraform 在執行 plan 或者 apply 命令時會自動加載這些文件,無需使用 -var-file 選項。.tfvars 文件中的定義會覆蓋變量的默認值和環境變量中的定義。如果要在命令行上替換 .tfvars 文件中設置的變量的值,可以使用 -var 選項,具體格式為 -var="<變量名>=<變量值>"
,比如想要在執行 terraform plan 的時候,將 vpc_name 指定為 "my-first-vpc",可以使用如下的方式:
$ terraform plan -var="vpc_name=my-fisrt-vpc"
此時 terraform plan 的輸出結果中,vpc_name 的值將顯示為 my-fisrt-vpc,而非 .tfvars 中定義的 my-vpc。此方法常用于自動化流程,其中 -var 從另一個環境變量獲取,并替換掉變量文件中事先定義好的值。
-var 選項的優先級最高,超過所有其他變量賦值方法。如果同時存在多種為變量賦值的方法,使用 -var 選項定義的值最終將賦給變量。
如果某個變量沒有使用以上所描述的方法設置變量值,那么 Terraform 會在運行 plan 或者 apply 的時候提示你。例如,在本例中,變量 vpc_name 未被賦值,如果在執行 terraform 命令的時候也沒有使用 -var 或者 -var-file 選項,則 CLI 將會提示你要輸入值:
變量的最佳實踐
當聲明變量的時候,我們提供以下幾條建議:
只參數化每個實例或環境中會變化的值
在決定是否暴露一個變量時,請確保你有具體的變更用例。如果一個變量只有很小的幾率需要使用,請不要暴露它。對帶有默認值的變量進行更改或新增是向后兼容的,但是移除某個變量則屬于非兼容性變更,需要額外注意。
盡可能使用 .tfvars 變量文件
對于根模塊,推薦使用 .tfvars 變量文件來為變量設置具體的值。盡可能避免在變量文件和命令行選項之間交替使用,命令行選項是臨時的,容易被遺忘,并且無法被提交到源代碼中進行版本控制,而默認的變量文件更具有可預測性。
給變量起與其使用目的相關的名稱
表示數值的變量,例如磁盤大小或者內存大小或者付費時長,盡可能在變量命名中使用單位。阿里云的 OpenAPI 沒有標準單位,因此遵循這種命名約定可以為 Terraform 配置文件的維護者明確預期的輸入單位。表示邏輯的變量,為了簡化條件邏輯,應給布爾變量取帶有肯定含義的名字,例如 enable_ipv6。
變量必須要有描述
描述會自動包含在文檔中,并為新的開發人員添加額外的上下文,增強 Terraform 配置文件的可讀性和可維護性。