我在
.tf
文件中定义了对多个应用程序通用的资源。我通过 .tfvars
文件填充许多字段。我需要完全基于 .tfvars
中的变量省略一些资源。
例如,如果我有这样的资源:
resource "cloudflare_record" "record" {
zone_id = "${data.cloudflare_zones.domain.zones[0].id}"
name = "${var.subdomain}"
value = "${var.origin_server}"
type = "CNAME"
ttl = 1
proxied = true
}
但是后来我在
cloudflare = false
文件中声明了类似 .tfvars
的内容,我希望能够执行以下操作:
if var.cloudflare {
resource "cloudflare_record" "record" {
zone_id = "${data.cloudflare_zones.domain.zones[0].id}"
name = "${var.subdomain}"
value = "${var.origin_server}"
type = "CNAME"
ttl = 1
proxied = true
}
}
我看过动态块,但看起来您只能使用它们来编辑资源中的字段和块。我需要能够忽略整个资源。
使用
count
中声明的变量添加带有三元条件的 .tfvars
参数,如下所示:
resource "cloudflare_record" "record" {
count = var.cloudflare ? 1 : 0
zone_id = "${data.cloudflare_zones.domain.zones[0].id}"
name = "${var.subdomain}"
value = "${var.origin_server}"
type = "CNAME"
ttl = 1
proxied = true
}
在此示例中,
var.cloudflare
是在.tfvars
文件中声明的布尔值。如果为真,将创建 1 record
的计数。如果为 false,将创建 0 record
计数。
在
count
应用后,资源成为一个组,因此稍后在参考中使用组的0-index
:
cloudflare_record.record[0].some_field
扩展@Joel Guerra的答案,在使用
count
确定是否部署资源后,您可以使用one()
函数来引用没有索引的资源(即不必使用[0]
) .
例如,定义如下资源后
resource "cloudflare_record" "record" {
count = var.cloudflare ? 1 : 0
}
定义一个局部变量,如下所示
locals {
cloudflare_record_somefield = one(cloudflare_record.record[*].some_field)
}
现在您可以使用
代替
cloudflare_record.record[0].some_field
local.cloudflare_record_somefield
如果计数为 0(例如
var.cloudflare
为 false
并且未创建资源),则 local.cloudflare_record_somefield
将返回 null
(而不是在使用 [0]
建立索引时返回错误)。
参考:https://developer.hashicorp.com/terraform/language/functions/one
我看到的一个问题是,如果您尝试创建的资源已经在使用 for_each ,那么您不能在资源中同时使用 count 和 for_each 。 我仍在尝试寻找答案,如果我找到更好的东西,我会更新。
示例场景:您可能想要创建或不创建(切换/使用标志/有条件创建)VM。但除了虚拟机之外,您可能还必须创建/不创建其负载均衡器、目标组和安全组等。
互联网上其他答案的问题是,当您在资源上使用三元运算符时,并且当您尝试在其他资源上引用它时,您总是会收到引用错误或索引错误或空元组错误。
要解决此问题,同时指向条件资源,您可以使用
try
语法
resource "aws_vpc" "main" {
count = var.test_flag ? 1 : 0
cidr_block = var.vpc_cidr
instance_tenancy = var.vpc_instance_tenancy
tags = {
Name = "${var.cluster_name}-vpc"
}
}
resource "aws_internet_gateway" "gw" {
count = try(var.test_flag ? 1 : 0, 0) // try block is important here because it has a dependency, here the VPC, but VPC might not need a try block because it is the parent.
vpc_id = aws_vpc.main[0].id
tags = {
Name = "${var.cluster_name}-IG"
}
}