【问题标题】:Terraform Interpolation in outputs输出中的 Terraform 插值
【发布时间】:2017-12-24 20:55:53
【问题描述】:

我根据环境是生产环境还是非生产环境来创建具有不同 KMS CMK 的 AWS RDS 实例。所以我有两个使用 terraform 计数的资源,如果:

count = "${var.bluegreen == "nonprod" ? 1 : 0}"

这会启动具有不同地址的不同 KMS 密钥的 RDS 实例。我需要捕获那个端点(我在构建完成后使用 terraform show 执行此操作),那么为什么这在 Terraform 中不起作用?

output "rds_endpoint" {
    value = "${var.bluegreen == "nonprod" ? aws_db_instance.rds_nonprod.address : aws_db_instance.rds_prod.address}"
}

【问题讨论】:

  • 我知道如何解决这个问题 - kms_key_id = "${var.bluegreen == "nonprod" ? "arn:aws:kms:eu-west-2:1234567890:key/foo" : " arn:aws:kms:eu-west-2:1234567890:key/bar"}" 在单个 aws_db_instance 资源中将 aws_db_instance 资源减少到一个(从两个)。

标签: amazon-web-services amazon-rds terraform


【解决方案1】:

访问具有count = 0 的资源的属性是错误的,不幸的是,Terraform 当前在其检查步骤中检查条件的两个“边”,因此这样的表达式可能会失败。除此之外,还有一种当前行为,即未明确显示输出中的错误,因为当状态尚未完成时(例如,由于使用 -target),可以填充输出。在这种情况下,这些烦恼都导致了很多混乱。

在这种情况下,与其使用条件表达式,不如使用“splat 表达式”,它在count = 0 的情况下计算为一个空列表。这看起来像下面这样:

output "rds_endpoint" {
    value = "${element(concat(aws_db_instance.rds_nonprod.*.address, aws_db_instance.rds_prod.*.address), 0)}"
}

这采用通过将所有非产品地址和所有产品地址连接在一起而创建的列表的第一个元素。由于您在这些资源块上配置 count 的方式,结果列表将永远只有一个元素,因此它只会采用该元素。

一般来说,要调试输出问题,评估 terraform console 或配置中的其他位置中的表达式会很有帮助,以绕过错误在输出上被静默忽略的限制。

【讨论】:

  • 很好的答案,我没有考虑过“splat 表达式”。从您的回答中,我可以假设我使用计数的方式可以使用另一种方法吗?我问,因为我看到了这种方法的意外行为 - 例如,当计数比较应该相同(蓝绿色仍然等于 nonprod)时,aws 安全组规则资源在第二次运行时被破坏。
  • 确实,element 函数存在一些挑战,如果你将任何 <computed> 传递给它——即使是部分传递——那么它的结果就会被计算出来,因为 Terraform 的核心保守地对待所有函数.在这种情况下,我没想到会出现问题,因为它看起来更像是一种“一种或另一种”的情况,但是如果您要创建一堆相关资源并在它们之间连接count.index,这会变得很棘手。只要bluegreen 保持设置为nonprod,这里的事情就应该是稳定的。
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 2023-01-24
  • 1970-01-01
  • 2020-12-07
  • 2019-10-28
  • 1970-01-01
  • 2019-12-12
  • 2020-06-09
相关资源
最近更新 更多