1

我正在编写一个Terraform脚本来启动 Google Cloud Platform 中的资源。
某些资源仅在设置另一个参数时才需要一个参数,仅在填充另一个参数(或任何其他类似条件)时如何填充一个参数?

例如:

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只有当 Advertisement_mode 是 CUSTOM 并且向路由器的所有对等方通告时,才能填充此字段。

现在,如果我保持DEFAULT的值,我的代码如下所示advertise_mode

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}"
    }
  }
}

上面的脚本工作正常,但是对我来说似乎有很多代码重复和黑客攻击。此外,对于(依赖属性的)两个选项是可以的,但是,如果有更多选项说 5,那么对于这样一个小东西的代码重复就太多了。有没有更好的方法来做我想要实现的目标?

4

2 回答 2

1

这几乎是您在 Terraform < 0.12 中受限的内容。一些资源允许您使用空字符串来省略基本值,并且提供者会将其解释为空值,而不是将其传递给 API 端点,因此它不会抱怨它没有正确设置。但根据我对 GCP 提供商的简短经验,大多数情况并非如此。

Terraform 0.12 引入了nullable 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}"
    }
  }
}

它还将引入您可以循环的动态块,因此您也可以拥有动态数量的advertised_ip_ranges块。

于 2019-04-25T15:55:59.650 回答
1

上述答案不正确,因为“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" 不会接受空值。

于 2020-12-18T01:44:15.480 回答