如何在terraform中有条件地填充参数值?

如何在terraform中有条件地填充参数值?,terraform,terraform-provider-aws,terraform-provider-gcp,Terraform,Terraform Provider Aws,Terraform Provider Gcp,我正在写一个脚本来加速谷歌云平台中的资源 某些资源仅当另一个参数已设置时才需要一个参数,如何仅在另一个参数已填充(或任何其他类似条件)时填充一个参数 例如: resource "google_compute_router" "compute_router" { name = "my-router" network = "${google_compute_network.foobar.name}" bgp { asn = 64514 a

我正在写一个脚本来加速谷歌云平台中的资源
某些资源仅当另一个参数已设置时才需要一个参数,如何仅在另一个参数已填充(或任何其他类似条件)时填充一个参数

例如:

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"
    }
  }
}
在上面的参考资料()中,
adverted_组
adverted_ip_范围
的描述都说只有当adverted_模式是自定义的并且向路由器的所有对等方播发时,才能填充此字段。

现在,如果我将
广告模式
的值保持为默认值,我的代码如下所示:

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"
    }
  }
}
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}"
    }
  }
}
但是,上述脚本在运行时会出现以下错误:

* 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" {
  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"
    }
  }
}
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),那么对于这样一个小东西,代码重复将太多。
有没有更好的方法来实现我想要实现的目标?

这几乎是Terraform<0.12中所限制的。一些资源允许您使用空字符串忽略基本值,并且提供程序会将其解释为空值,而不会将其传递给API端点,因此不会抱怨未正确设置。但根据我与GCP提供商的短暂经验,那里的大多数情况并非如此

Terraform 0.12引入了一种允许您使用以下内容有条件地设置这些参数的方法:

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

它还将介绍您可以循环,这样您也可以拥有动态数量的
广告ip\u范围
块。

上述答案不正确,因为“广告ip\u范围”不接受空值;解决方案是利用一个动态块,它可以处理该资源的空值,并进一步使该资源能够接受可变数量的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.adverted_ip_ranges.0.range”不接受空值。

我在terraform网站上读到了这一点。使用0.12测试版临时编写脚本并确保在0.12发布后进行更改是一个好主意吗?另外,你知道下一个版本什么时候发布吗?Terraform 0.12最初计划在2018年夏末发布,但遇到了一系列困难,所以我认为现在尝试猜测发布日期是不公平的。我不会用它来制作东西,主要是因为他们在这一点上提出了警告,而且很久以前我有一些不太稳定的地形版本的恐怖故事。现在(如果您想要的只是这个特定的东西),我会坚持使用您的复制代码,并在发布时移到0.12。堆栈溢出和堆栈交换通常不在帖子中使用签名。你的用户卡显示在你发表的每一篇文章的右下角。如果你希望你的联系信息是公开的,那么可以在你的个人资料页面,你的用户卡链接到该页面。像您在这里所做的那样,添加签名通常被认为是垃圾邮件。这也有助于你在这个答案上获得选票。