You need to enable JavaScript to run this app.
导航

Metadata

最近更新时间2022.07.01 10:39:21

首次发布时间2022.05.17 12:06:31

Metadata是Terraform中的内置元参数,可以在ProviderResourceData Sources块中使用。
本文为您介绍Resource块支持的元参数及其作用:

  • depends_on:指定资源的依赖项。
  • count:创建多个相同配置的资源。
  • for_each:根据映射、字符串集合创建多个资源。
  • provider:选择非默认的provider。
  • lifecycle:定制资源的生命周期。

depends_on

一个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
  ...
}

count

默认情况下,一个Resource块只允许配置一个资源。当需要创建多个相同的资源时,配置多个独立的resource块会使代码冗余且不利维护,此时,您可以使用count或for_each参数在同一个resource块中管理多个相同的资源。

说明

同一个resource块中不允许同时使用count或for_each参数。

  • 如果资源的参数完全一致或大部分一致时,建议使用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

for_each与count相似,不同的是,for_each使用键值对或字符串集合的形式将值映射到对应的属性中。

  • 键值对:使用each.keyeach.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块创建多个配置,默认块唯一且使用"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

每个资源实例在生命周期中都会经历创建、更新和删除三个阶段,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
        }
      }