本文將介紹資源依賴關係。
在構建基礎設施時,您可能希望有一個可視化的依賴圖來表示基礎設施架構,進而瞭解您的基礎設施是如何串連和相互依賴的。
Terraform 在執行時,會從你的設定檔中自動構建依賴圖,進而產生執行計畫並重新整理狀態。例如一個建立 ECS 的設定檔:
provider "alicloud" {
# 配置你的阿里雲憑據和地區資訊
# 配置你的阿里雲憑據,出於安全考慮,建議不要在這個檔案中直接包含你的阿里雲AccessKey和SecretKey,推薦使用環境變數或其它安全方式設定憑據:
# export ALICLOUD_ACCESS_KEY="<你的阿里雲Access Key>"
# export ALICLOUD_SECRET_KEY="<你的阿里雲Secret Key>"
region = "cn-hangzhou"
}
# 建立 VPC
resource "alicloud_vpc" "my_vpc" {
vpc_name = "main-vpc"
cidr_block = "10.0.0.0/16"
}
# 建立 VSwitch
resource "alicloud_vswitch" "my_vswitch" {
vpc_id = alicloud_vpc.my_vpc.id
cidr_block = "10.0.1.0/24"
zone_id = "cn-hangzhou-h"
vswitch_name = "main-vswitch"
}
# 建立安全性群組
resource "alicloud_security_group" "my_sg" {
vpc_id = alicloud_vpc.my_vpc.id
name = "main-security-group"
}
# 配置安全性群組規則允許 SSH 訪問
resource "alicloud_security_group_rule" "allow_ssh" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = alicloud_security_group.my_sg.id
cidr_ip = "0.0.0.0/0"
}
# 建立 ECS 執行個體
resource "alicloud_instance" "my_instance" {
instance_name = "Ubuntu20-Instance"
image_id = "ubuntu_20_04_x64_20G_alibase_20240508.vhd" # Ubuntu 20.04 的鏡像 ID
instance_type = "ecs.c6.large" # 2核4G
security_groups = [alicloud_security_group.my_sg.id]
vswitch_id = alicloud_vswitch.my_vswitch.id
internet_charge_type = "PayByTraffic"
instance_charge_type = "PostPaid"
system_disk_category = "cloud_efficiency"
password = "Abc@12345" # 設定登入密碼
internet_max_bandwidth_out = 10 # 設定頻寬大於 0,自動分配公網 IP
tags = {
Name = "ubuntu20"
}
}ECS 執行個體的建立同時依賴於安全性群組和 vSwitch 的建立,依賴關係的建立是通過屬性值 security_groups 和 vswitch_id 的賦值來建立依賴關係,Terraform 在執行時通過建立依賴圖來確定資源操作的正確順序。在有多個資源的複雜情況下,對於不存在依賴關係的資源,Terraform 將並存執行操作。
依賴關係
Terraform 有兩種依賴關係:隱式依賴(Implicit Dependence)和顯式依賴(Explicit Dependence)。隱式依賴是 Terraform 已知的,而顯式依賴是未知的。
隱式依賴(Implicit Dependence)
當一個資源的建立依賴於另一個資源建立後的資訊時,需要用到隱式依賴來讓 Terraform 知曉依賴關係。
在這個樣本中,vSwitch 和安全性群組的建立依賴於 VPC;ECS 執行個體的建立依賴於 vSwitch 和安全性群組;安全性群組規則的建立依賴於安全性群組,這些依賴關係是隱式的。
針對隱式依賴關係,Terraform 通過屬性值引用賦值的方式來知曉。
例如,instance 的 vswitch_id 參數值是對 my_vswitch 資源的引用,進而建立了 instance 資源對 vSwitch 資源的隱式依賴關係。
針對隱式依賴關係,Terraform 能夠推斷出依賴關係並根據這些依賴關係知道不同資源建立的順序,進而確保設定檔中定義的所有資源都能按照這個順序建立成功。
在這個例子中,資源之間的依賴關係和建立順序正如下圖所示:
當 Terraform 讀取配置時,它將首先確保 vpc my_vpc 在 vswtich my_vswitch 和安全性群組 my_sg 之前建立,同時也會確保在 ECS 執行個體 my_instance 會在 my_vswitch 和 my_sg 之後完成建立。然後,將所有資源的屬性儲存在狀態檔案中,並將 my_vswitch 和 my_sg 中的 vpc_id 參數設定為 my_vpc 的 id 的值,將 my_instance 的 vswitch_id 和 security_groups 的值設定為 my_vswitch 和 my_sg 的值。
顯示依賴(Explicit Dependence)
有時,某個資源只能在另一個資源建立後才能建立,在這種情況下,你需要顯式地引入依賴關係,該依賴關係配置在 Terraform 配置代碼內部,對 Terraform 不可見。在這種情況下,你可以使用 depends_on 來顯式聲明依賴關係。
depends_on 參數給你更多的靈活性來控制 Terraform 在配置中處理資源的順序。無論資源類型是什麼,depends_on 可以在模組內使用,該值可以是指向資源的運算式。
例如,假設你需要在上述例子的基礎上再增加兩個連接埠 443 和 8080 的訪問規則,並希望 8080 連接埠規則在 443 連接埠規則建立成功之後才建立。這種依賴關係對 Terraform 不可見,必須顯式提及。你可以使用 depends_on 顯式聲明 8080 連接埠規則對 443 連接埠規則的依賴:
在通過運算式賦值時,Terraform 將處理元參數 depends_on 中指定的資源,並確保在建立 8080 訪問規則之前先建立 443 訪問規則。在執行 terraform apply 後,你將注意到 8080 訪問規則是在 443 訪問規則之後建立的。
最後,我們需要注意的是,資源定義的順序並不會影響 Terraform 執行的方式,因此你可以按照對你和你的團隊最有意義的方式來組織設定檔。