Metadata是Terraform中的内置元参数,可以在Provider、Resource、Data Sources块中使用。
本文为您介绍Resource块支持的元参数及其作用:
一个Terraform配置文件中可能包含多个资源,通过资源之间的引用逻辑即可自动推断出资源的依赖关系。而对于某些不可见的资源依赖关系,则需要通过depends_on创建显式依赖,depends_on可以更改资源的创建顺序或执行顺序,使其在所依赖的资源之后处理。
depends_on的表达式是依赖资源的地址列表,例如我们串行创建一个VPC、子网和安全组,并且假设安全组必须在子网创建之后创建:
resource "volcengine_vpc" "vpc" { ... } #子网会在VPC完成之后被串行创建 resource "volcengine_subnet" "subnet" { vpc_id = volcengine_vpc.id ... } #安全组会在子网完成后才会创建,如果不使用depends_on,子网和安全的创建会出现并行调度 resource "volcengine_security_group" "sg" { depends_on = [volcengine_subnet.subnet] vpc_id = volcengine_vpc.id ... }
默认情况下,一个Resource块只允许配置一个资源。当需要创建多个相同的资源时,配置多个独立的resource块会使代码冗余且不利维护,此时,您可以使用count或for_each参数在同一个resource块中管理多个相同的资源。
说明
同一个resource块中不允许同时使用count或for_each参数。
当需要创建3个相同配置的云盘时,示例如下:
resource "volcengine_volume" "foo" { count = 3 volume_name = "terraform-test" zone_id = "cn-beijing-a" volume_type = "PTSSD" kind = "data" size = 40 }
如果您对资源的某些参数有唯一性要求,可以使用count.index
属性区分,标识从0开始计数。假设创建两个VPC,名称为tf_vpc_0和tf_vpc_1,示例如下:
resource "volcengine_vpc" "vpcs" { count = 2 vpc_name = "tf_vpc_${count.index}" cidr_block = "172.20.0.0/16" }
基于以上示例,如果您想为不同的VPC指定不同掩码,可以声明一个string列表存储不同VPC的掩码值,然后通过count.index
访问列表元素。示例如下:
variable "name_list" { type = list(string) default = ["tf_vpc_test1", "tf_vpc_test2"] } variable "cidr_list" { type = list(string) default = ["172.20.0.0/16", "172.21.0.0/16"] } resource "volcengine_vpc" "vpcs" { count = 2 vpc_name = var.name_list[count.index] cidr_block = var.cidr_list[count.index] }
访问count创建的资源时,需要使用索引值,格式为:<资源类型>.<名称>[索引值]。示例如下:
# 访问第一个VPC > volcengine_vpc.vpcs[0] # 访问第一个VPC的ID > volcengine_vpc.vpcs[0].id # 访问所有VPC的ID > volcengine_vpc.vpcs[*].id
for_each与count相似,不同的是,for_each使用键值对或字符串集合的形式将值映射到对应的属性中。
键值对:使用each.key
和each.value
访问键和值。
例如创建VPC时,通过for_each
中的键值对,可以灵活配置VPC的名称和掩码。
resource "volcengine_vpc" "vpc" { for_each = { tf_vpc_test1 = "172.20.0.0/16" tf_vpc_test2 = "172.21.0.0/16" } vpc_name = each.key cidr_block = each.value }
字符串集合:each.key
等同于each.value
,统一使用each.key
表示,且可以通过toset()
函数将定义的list类型进行转化:
# to_set list => set resource "volcengine_security_group" "sg" { for_each = toset(["tf_sg_test1", "tf_sg_test2"]) name = each.key } # 通过变量表示 for_each variable "sg_name" { type = set(string) } resource "volcengine_security_group" "sg" { for_each = var.sg_name name = each.key }
访问for_each创建的资源时,格式为:<资源类型>.<名称>[键名]。示例如下:
# 访问 tf_vpc_test1 > volcengine_vpc.vpcs["tf_vpc_test1"] # 访问 tf_vpc_test1 的ID > volcengine_vpc.vpcs["tf_vpc_test1"].id
您可以使用provider块创建多个配置,默认块唯一且使用"provider"标识,其它非默认块使用"alias"标识。如果您需要在不同的地域管理资源,需要声明多个provider块。如下所示,示例中声明了华北(cn-beijing)和华东地域(cn-nantong)的火山引擎provider,并对华东的provider增加了别名:
provider "volcengine" { region = "cn-beijing" ... } provider "volcengine" { alias = "ntcc" region = "cn-nantong" ... }
选择非默认块时,格式为:<provider名称>.<别名>,如下所示,所选provider为volcengine.ntcc:
resource "volcengine_vpc" "foo" { provider = volcengine.ntcc vpc_name = "tf-test-2" cidr_block = "172.16.0.0/16"
每个资源实例在生命周期中都会经历创建、更新和删除三个阶段,lifecycle可以改变资源生命周期的过程,支持以下参数:
create_before_destroy
默认情况下,当需要改变资源中不支持更新的参数时,Terraform会先销毁已有实例,再使用新配置的参数创建新实例进行替换。而当create_before_destroy参数设置为true
时,Terraform将先创建新实例,再销毁已有实例,使业务不中断。示例如下:
lifecycle { create_before_destroy = true }
说明
使用create_before_destroy时,由于新旧实例会同时存在,请提前确认资源实例是否有唯一的名称要求或其他约束。
prevent_destroy
当想要阻止资源的删除操作时,可以将prevent_destroy参数设置为true
,防止意外操作。如果想要正常删除此资源,只需删除prevent_destroy参数后再执行删除操作即可。
lifecycle { prevent_destroy = true }
ignore_changes
默认情况下,执行terraform plan/apply
命令时会自动检测云上资源的属性和本地资源块中的差异,不一致即会更新或重建以匹配配置。如果您不想自动检测,可以使用 ignore_changes忽略某些参数。
ignore_changes的值可以是属性的相对地址列表,对于Map和List类型,也可以使用索引表示法引用,例如tags["Name"]、list[0]。
instance_name
:resource "volcengine_ecs_instance" "foo" { ... lifecycle { ignore_changes = [ instance_name, ] } }
all
,示例如下:resource "volcengine_ecs_instance" "foo" { ... lifecycle { ignore_changes = all } }