【问题标题】:How to refer to alternate resources in Terraform?如何在 Terraform 中引用备用资源?
【发布时间】:2018-12-12 13:45:36
【问题描述】:

Terraform(截至今天)有一些令人不安的限制,即您无法创建具有内插(计算)lifecycle 属性 prevent_destroy 的资源。

解决方法的代码非常简单,只需创建 2 个具有“交替”计数的资源。当您有 1 个不允许销毁的“生产”资源时,您有 0 个可以销毁的“测试”资源。或者反过来。 (请参阅链接的stackoverflow问题的答案 详情见上面。)

但是,这带来了一个新问题。当我想引用“为此执行而存在的备用资源之一”时,我该怎么做?

类似的伪代码

"${local.production ? "${aws_eip.commander_production.public_ip}" : "${aws_eip.commander_testing.public_ip}" }" 

这个伪代码不能工作有几个原因:

  • aws_eip.commander_production 不再是单个资源,它是一个列表,所以你需要* 语法
  • 其中一个列表始终为空,Terraform 很容易抱怨它无法确定空列表的类型。 (我猜是因为三元运算符要求替代项具有相同的类型)
  • 当您访问一个空列表时,您会收到一个错误(使用 C 语义,未使用的备用将不会被评估,但 Terraform 的工作方式似乎不同,我在尝试编写此代码时出错)

为了解决这些问题,我想出了以下 hacky 解决方案: 最后用一个虚拟元素扩展列表,然后参考 扩展列表的第一个元素。这个代码很漂亮 打字很糟糕,但它似乎有效

locals  {
  dummy = [ "foo" ]
}


output "0101: address" {
  value = "${format("Public IP is %s", "${local.production ? "${element("${concat("${aws_eip.commander_production.*.public_ip}", "${local.dummy}")}", 0)}" : "${element("${concat("${aws_eip.commander_testing.*.public_ip}", "${local.dummy}")}", 0)}" }")}"

}

问题:什么是更短/更优雅的编码方式?

注意:我自己找到了一个答案,但欢迎贡献更好的答案。

【问题讨论】:

    标签: terraform


    【解决方案1】:

    有点短的代码是

    output "0101: address" {
       value = "${format("Public IP is %s", "${element("${concat("${aws_eip.commander_production.*.public_ip}", "${aws_eip.commander_testing.*.public_ip}")}", 0)}")}"
    

    }

    纯文本:连接列表并获取结果的第一个元素。一个列表有一个元素,另一个为零,因此无论该元素是在第一个列表还是第二个列表中,结果都是我们想要的。

    【讨论】:

      猜你喜欢
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 2023-02-08
      • 2021-12-11
      • 2020-12-09
      • 2021-06-08
      • 2021-09-12
      • 2021-12-14
      相关资源
      最近更新 更多