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
不再是单个资源,而是一个列表,因此您需要*
语法要解决这些问题,我想出了以下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)}" }")}"
}
问题:什么是对此进行编码的更简短/更优雅的方法?
注意:我自己找到了一个答案,但欢迎为更好的答案做出贡献。
答案 0 :(得分:0)
较短的代码是
output "0101: address" {
value = "${format("Public IP is %s", "${element("${concat("${aws_eip.commander_production.*.public_ip}", "${aws_eip.commander_testing.*.public_ip}")}", 0)}")}"
}
以纯文本格式:连接列表并采用结果的第一个元素。一个列表具有一个元素,而另一个列表为零,因此结果将是我们想要的结果,而不管元素是在第一列表还是第二列表中。