【发布时间】:2018-12-12 13:45:36
【问题描述】:
Terraform(截至今天)有一些令人不安的限制,即您无法创建具有内插(计算)lifecycle 属性 prevent_destroy 的资源。
- Terraform: How to get a boolean from interpolation?
- https://github.com/hashicorp/terraform/issues/3116
解决方法的代码非常简单,只需创建 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