如何有条件地填充 terraform 中的参数值?
How to conditionally populate an argument value in terraform?
我正在编写一个 Terraform 脚本来启动 Google 云平台中的资源。
有些资源仅在另一个参数设置时才需要一个参数,如何仅在另一个参数已填充(或任何其他类似条件)时填充一个参数?
例如:
resource "google_compute_router" "compute_router" {
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
advertised_ip_ranges {
range = "1.2.3.4"
}
advertised_ip_ranges {
range = "6.7.0.0/16"
}
}
}
在上述资源 (google_compute_router) 中,advertised_groups
和 advertised_ip_ranges
的描述都说 只有在 advertise_mode 是CUSTOM 并向路由器的所有对等点通告。
现在,如果我将 advertise_mode
的值保留为 DEFAULT,我的代码如下所示:
resource "google_compute_router" "compute_router" {
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
#Changin only the value below
advertise_mode = "DEFAULT"
advertised_groups = ["ALL_SUBNETS"]
advertised_ip_ranges {
range = "1.2.3.4"
}
advertised_ip_ranges {
range = "6.7.0.0/16"
}
}
}
上面的脚本在 运行 上给出了以下错误:
* google_compute_router.compute_router_default: Error creating Router: googleapi: Error 400: Invalid value for field 'resource.bgp.advertiseMode': 'DEFAULT'. Router cannot have a custom advertisement configurati
on in default mode., invalid
作为上述问题的解决方法,我创建了两个名称不同的资源来做几乎相同的事情。该脚本如下所示:
resource "google_compute_router" "compute_router_default" {
count = "${var.advertise_mode == "DEFAULT" ? 1 : 0}"
name = "${var.router_name}"
region = "${var.region}"
network = "${var.network_name}"
bgp {
asn = "${var.asn}"
advertise_mode = "${var.advertise_mode}"
#Removed some codes from here
}
}
resource "google_compute_router" "compute_router_custom" {
count = "${var.advertise_mode == "CUSTOM" ? 1 : 0}"
name = "${var.router_name}"
region = "${var.region}"
network = "${var.network_name}"
bgp {
asn = "${var.asn}"
advertise_mode = "${var.advertise_mode}"
advertised_groups = ["${var.advertised_groups}"]
advertised_ip_ranges {
range = "${var.advertised_ip_range}"
description = "${var.advertised_ip_description}"
}
}
}
上面的脚本工作正常,但对我来说似乎有很多代码重复和 hack。此外,对于(依赖属性的)两个选项很好,但是,如果有更多选项,比如 5,那么对于这么小的东西的代码重复就太多了。
有没有更好的方法来实现我想要实现的目标?
这几乎是您在 Terraform < 0.12 中的限制。某些资源允许您使用空字符串来省略基本值,并且提供者会将其解释为空值,而不会将其传递给 API 端点,因此它不会抱怨未正确设置。但根据我与 GCP 提供商的短暂经验,那里的大多数情况并非如此。
Terraform 0.12 引入了 null
able arguments,它允许您使用如下内容有条件地设置这些:
variable "advertise_mode" {}
resource "google_compute_router" "compute_router" {
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
advertise_mode = "${var.advertise_mode}"
advertised_groups = ["${var.advertise_mode == "DYNAMIC" ? ALL_SUBNETS : null}"]
advertised_ip_ranges {
range = "${var.advertise_mode == "DYNAMIC" ? 1.2.3.4 : null}"
}
advertised_ip_ranges {
range = "${var.advertise_mode == "DYNAMIC" ? 6.7.0.0/16 : null}"
}
}
}
它还将介绍 dynamic blocks,您可以循环,因此您也可以拥有动态数量的 advertised_ip_ranges
块。
以上答案不正确,因为 'advertised_ip_ranges' 不接受空值;对此的解决方案是利用一个动态块,该块可以处理该资源的空值,并进一步使该资源能够接受可变数量的 ip 范围。
variable custom_ranges {
default = ["172.16.31.0/24","172.16.32.0/24"]
}
resource "google_compute_router" "router_01" {
name = "cr-bgp-${var.gcp_bgp_asn}"
region = var.gcp_region
project = var.gcp_project
network = var.gcp_network
bgp {
asn = var.gcp_bgp_asn
advertise_mode = var.advertise_mode
advertised_groups = var.advertise_mode == "CUSTOM" ? ["ALL_SUBNETS"] : null
dynamic "advertised_ip_ranges" {
for_each = var.advertise_mode == "CUSTOM" ? var.custom_ranges : []
content {
range = advertised_ip_ranges.value
}
}
}
}
其他搜索键:google_compute_router“bgp.0.advertised_ip_ranges.0.range”不接受空值。
我正在编写一个 Terraform 脚本来启动 Google 云平台中的资源。
有些资源仅在另一个参数设置时才需要一个参数,如何仅在另一个参数已填充(或任何其他类似条件)时填充一个参数?
例如:
resource "google_compute_router" "compute_router" {
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
advertised_ip_ranges {
range = "1.2.3.4"
}
advertised_ip_ranges {
range = "6.7.0.0/16"
}
}
}
在上述资源 (google_compute_router) 中,advertised_groups
和 advertised_ip_ranges
的描述都说 只有在 advertise_mode 是CUSTOM 并向路由器的所有对等点通告。
现在,如果我将 advertise_mode
的值保留为 DEFAULT,我的代码如下所示:
resource "google_compute_router" "compute_router" {
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
#Changin only the value below
advertise_mode = "DEFAULT"
advertised_groups = ["ALL_SUBNETS"]
advertised_ip_ranges {
range = "1.2.3.4"
}
advertised_ip_ranges {
range = "6.7.0.0/16"
}
}
}
上面的脚本在 运行 上给出了以下错误:
* google_compute_router.compute_router_default: Error creating Router: googleapi: Error 400: Invalid value for field 'resource.bgp.advertiseMode': 'DEFAULT'. Router cannot have a custom advertisement configurati
on in default mode., invalid
作为上述问题的解决方法,我创建了两个名称不同的资源来做几乎相同的事情。该脚本如下所示:
resource "google_compute_router" "compute_router_default" {
count = "${var.advertise_mode == "DEFAULT" ? 1 : 0}"
name = "${var.router_name}"
region = "${var.region}"
network = "${var.network_name}"
bgp {
asn = "${var.asn}"
advertise_mode = "${var.advertise_mode}"
#Removed some codes from here
}
}
resource "google_compute_router" "compute_router_custom" {
count = "${var.advertise_mode == "CUSTOM" ? 1 : 0}"
name = "${var.router_name}"
region = "${var.region}"
network = "${var.network_name}"
bgp {
asn = "${var.asn}"
advertise_mode = "${var.advertise_mode}"
advertised_groups = ["${var.advertised_groups}"]
advertised_ip_ranges {
range = "${var.advertised_ip_range}"
description = "${var.advertised_ip_description}"
}
}
}
上面的脚本工作正常,但对我来说似乎有很多代码重复和 hack。此外,对于(依赖属性的)两个选项很好,但是,如果有更多选项,比如 5,那么对于这么小的东西的代码重复就太多了。 有没有更好的方法来实现我想要实现的目标?
这几乎是您在 Terraform < 0.12 中的限制。某些资源允许您使用空字符串来省略基本值,并且提供者会将其解释为空值,而不会将其传递给 API 端点,因此它不会抱怨未正确设置。但根据我与 GCP 提供商的短暂经验,那里的大多数情况并非如此。
Terraform 0.12 引入了 null
able arguments,它允许您使用如下内容有条件地设置这些:
variable "advertise_mode" {}
resource "google_compute_router" "compute_router" {
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
advertise_mode = "${var.advertise_mode}"
advertised_groups = ["${var.advertise_mode == "DYNAMIC" ? ALL_SUBNETS : null}"]
advertised_ip_ranges {
range = "${var.advertise_mode == "DYNAMIC" ? 1.2.3.4 : null}"
}
advertised_ip_ranges {
range = "${var.advertise_mode == "DYNAMIC" ? 6.7.0.0/16 : null}"
}
}
}
它还将介绍 dynamic blocks,您可以循环,因此您也可以拥有动态数量的 advertised_ip_ranges
块。
以上答案不正确,因为 'advertised_ip_ranges' 不接受空值;对此的解决方案是利用一个动态块,该块可以处理该资源的空值,并进一步使该资源能够接受可变数量的 ip 范围。
variable custom_ranges {
default = ["172.16.31.0/24","172.16.32.0/24"]
}
resource "google_compute_router" "router_01" {
name = "cr-bgp-${var.gcp_bgp_asn}"
region = var.gcp_region
project = var.gcp_project
network = var.gcp_network
bgp {
asn = var.gcp_bgp_asn
advertise_mode = var.advertise_mode
advertised_groups = var.advertise_mode == "CUSTOM" ? ["ALL_SUBNETS"] : null
dynamic "advertised_ip_ranges" {
for_each = var.advertise_mode == "CUSTOM" ? var.custom_ranges : []
content {
range = advertised_ip_ranges.value
}
}
}
}
其他搜索键:google_compute_router“bgp.0.advertised_ip_ranges.0.range”不接受空值。