在瞭解了模板編寫、Terraform 設定檔目錄和 HashiCorp 語言 HCL 之後,本文主要介紹在 Terraform 工作流程的代碼編寫階段您會遇到的一些常見術語和概念。
資源(Resources)
資源(Resources)是定義基礎設施組件的代碼塊,通常定義在 main.tf 檔案中。資源通過關鍵字 resource 來標識,之後是具體的資源類型和自訂名稱。資源類型取決於您在設定檔中定義的供應商(Provider)。在花括弧內是指定資源類型的參數,您需要在這裡指定資源配置所需的輸入。
resource "resource_type" "resource_name" {
# 指定資源類型的參數(Argument)
}Terraform 使用資源類型和資源名稱來標識一個基礎設施元素。關鍵字 resource 將代碼塊識別為雲基礎設施的組件。資源類型是 alicloud_oss_bucket,這代表阿里雲的資源。術語 resource 是 Terraform 特有的,不能自訂;資源類型根據定義的供應商而變化;example-bucket 代表在當前 Terraform 配置中的資源名稱。Terraform 使用資源類型和資源名稱一起作為資源在當前 Terraform 配置中的標識符。
resource "alicloud_oss_bucket" "example-bucket" {
bucket = "my-bucket-xxxx" # 指定一個全域唯一的 Bucket 名稱
}下面這個樣本聲明了阿里雲為提供者,並展示了兩個阿里雲的資源塊:一個 OSS Bucket 和一個虛擬交換器。參數根據定義的資源類型而不同。對於資源 alicloud_oss_bucket,你只需指定 Bucket 名稱即可成功建立資源。對於 alicloud_vswitch 資源,你必須指定所屬 VPC 的 ID(vpc_id)、網段(cidr_block)、所屬可用性區域(zone_id),名稱,標籤等其他參數是可選的。
resource "alicloud_oss_bucket" "example-bucket" {
bucket = "my-bucket-xxxxx"
}
resource "alicloud_vswitch" "main_vswitch" {
vpc_id = "vpc-abc12345"
cidr_block = "10.0.1.0/24"
zone_id = "cn-hangzhou-k"
vswitch_name = "main-vswitch"
}如果資源複雜,資源配置代碼較長,可以按照資源類型單獨使用一個獨立的 .tf 檔案來存放,例如,用於 ECS 執行個體、OSS Bucket 和資料庫的配置可以分別放在 instance.tf,oss.tf 和 database.tf 中。
供應商(Provider)
供應商實現了每一種可配置的資源類型;如果沒有供應商,Terraform 將無法管理任何類型的基礎設施。供應商通常定義在 providers.tf 檔案中,您需要指定包含供應商定義的 Terraform 塊。當聲明了供應商後,Terraform 通過 init 命令自動下載供應商外掛程式。
terraform {
required_providers {
alicloud = {
source = "aliyun/alicloud"
version = "1.225.0"
}
}
}
provider "alicloud" {
# 配置你的阿里雲憑據和地區資訊
# 出於安全考慮,建議不要在這個檔案中直接包含你的阿里雲AccessKey和SecretKey,推薦使用環境變數或其它安全方式設定憑據:
# export ALICLOUD_ACCESS_KEY="<你的阿里雲Access Key>"
# export ALICLOUD_SECRET_KEY="<你的阿里雲Secret Key>"
region = "cn-hangzhou"
}供應商將具體的管理資源的 API 編排為 Terraform 資源,並管理資源與 API 之間的互動。供應商配置屬於 Terraform 配置的根模組。alicloud 是要配置的本地供應商名稱,為了確保本地名稱配置正確,必須在 required_providers 塊中包含供應商。source 參數用於指定您打算使用的供應商的全域源地址。在上面的樣本中,source 參數被賦值為 Terraform Registry 網站的地址 aliyun/alicloud。version 參數用於指定供應商的其中一個版本,該參數是可選的,但建議使用。version 參數將供應商限制在特定版本或版本範圍內,以防止下載可能包含非相容更改的新供應商。如果未指定版本,Terraform 會在初始化期間自動下載最新版本的供應商。
值得注意的是,由於歷史原因,阿里雲供應商 alicloud 支援兩個 source 值:aliyun/alicloud 和 hashicorp/alicloud。兩者的實現完全一致。更多資訊,詳見Terraform 概覽。
access_key,secret_key,region 等參數是專用於配置阿里雲 Provider 的。如果 Terraform 配置中沒有包含 provider 塊,Terraform 會假定一個空的預設配置,並且 access_key,secret_key,region 預設會從環境變數中擷取。如果環境變數中沒有指定 region,預設將使用 cn-beijing。更多阿里雲 Provider 的配置參數,詳見 Provider 官網。
變數(Variables)
變數用於參數化你的 Terraform 配置。輸入變數作為參數供給 Terraform 使用,使其允許在無需更改源配置代碼的情況下輕鬆定製和共用配置。一旦定義了變數,在 Terraform 運行時可以有多種不同的方式來設定其值:環境變數、CLI 參數、索引值檔案等。你可以在運行時或在一個以 .tfvars 副檔名結尾的檔案中以 K-V 的形式定義資源屬性。
藉助參數,你可以輕鬆地將屬性與 Terraform 執行計畫分離。在這個樣本中,main.tf 聲明了一個Virtual Private Cloud,vpc_name 屬性在 variables.tf 檔案中被聲明為變數,因此該屬性已經被參數化,你可以在運行時定義這些變數的值或者將其定義到一個 tfvars 檔案中。更多關於變數的內容,詳見Variable。
輸出(Outputs)
outputs.tf 檔案儲存了資源的輸出值。由 Terraform 管理的每個資源執行個體都可以匯出屬性,這些屬性的值可在 Terraform 配置的其他地方被引用。如果需要,輸出值是用來暴露這些資訊的方法。
一些資源屬性在建立時被計算出來。例如,某些資源的串連地址或者 vSwitch 的 ID 會在資源建立時產生。vSwitch 的計算屬性 ID 是建立其他資源(如 ECS 執行個體,RDS 執行個體等)對象所需的。通過輸出值,您可以輸出這些資訊並使其可訪問。
output "vswitch_id" {
value = alicloud_vswitch.main_vswitch.id
}output 關鍵字後的標籤是名稱,必須是一個有效標識符。在根模組中,此名稱會顯示給查看者。在子模組中,它可以用於訪問該值。value 參數接受一個運算式,該運算式返回結果給使用者。

狀態(State)
Terraform 在狀態檔案中儲存它管理的資源的狀態。預設情況下,狀態檔案是儲存在本地,但它也可以遠端儲存。在團隊協作情境中,遠端儲存通常是首選方法。
{
"version": 4,
"terraform_version": "1.7.1",
"serial": 168,
"lineage": "46c0889c-f4ff-d1fd-2109-364f97e55c06",
"outputs": {
"vswitch_id": {
"value": "vsw-bp1ev5ei73c7y5ib887v1",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "alicloud_vswitch",
"name": "main_vswitch",
"provider": "provider[\"registry.terraform.io/hashicorp/alicloud\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"availability_zone": "cn-hangzhou-k",
"cidr_block": "10.0.1.0/24",
"create_time": "2024-06-23T07:53:48Z",
"description": "",
"enable_ipv6": null,
"id": "vsw-bp1ev5ei73c7y5ib887v1",
...需要注意的是,不要修改或觸碰此檔案,它是自動建立和更新的,一旦狀態檔案損壞,將會導致繼續執行 Terraform 失敗或者重複建立新的資源。更多狀態介紹,詳見狀態原理介紹。
模組(Modules)
Terraform 模組是一組位於單個目錄中的 Terraform 設定檔,即使是一個包含了一個或多個 .tf 檔案的單一目錄的簡單配置也被視為一個模組。模組是 Terraform 中代碼複用的主要方法,它們通過指定可以檢索代碼的源來重複使用。源可以是本地的也可以是遠端。你可以使用來自 HashiCorp 模組註冊中心的開源模組或建立你自己的模組。
