Terraform输出中的插值

问题描述:

根据环境是生产还是非生产,我使用不同的KMS CMK创建AWS RDS实例。所以,我有使用如果terraform计数两种资源:Terraform输出中的插值

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

这与不同的地址不同的KMS密钥旋转起来的RDS实例。我需要捕获该端点(在构建完成后我使用terraform显示完成),那么为什么不在Terraform中工作?

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

我知道如何解决此问题 - 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资源减少为一个(从两个)。 – Chris

这是访问具有count = 0资源的属性,可惜Terraform目前在其检查步骤,检查两个条件的“面”,所以像这样的表述可能会失败的错误。与此同时,目前的行为是输出中的错误没有明确显示,因为当状态尚未完成时(例如,由于使用了-target)输出可能会被填充。在这种情况下,这些烦恼总结了很多混乱。

在这种情况下,使用“splat表达式”可以更好地使用“splat表达式”,该表达式在count = 0的情况下评估为空列表。这看起来像下面这样:

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

这需要通过连接在一起的所有nonprod地址和所有督促地址创建的列表的第一个元素。由于您如何在这些资源块上配置count,因此生成的列表将只有一个元素,因此它只会采用该元素。

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

+0

很好的回答,我没有考虑过“splat表达式”。从我的答案中,我可以假设另一种方法可用于我已经使用的方法?我问,因为我看到了这种方法的意外行为 - 例如,当计数比较应该相同时(蓝绿色仍然等于nonprod),第二次运行时会破坏aws安全组规则资源。 – Chris

+0

事实上,如果你传递任何“” - 即使是部分 - 都会遇到一些挑战,那么它的结果就会被计算出来,因为Terraform的核心部分保守地处理所有函数。在这种情况下,我没有预料到问题,因为它看起来更像是“一种或另一种”情况,但是如果你用'count.index'连接它们来创建一堆相关资源,这会变得棘手。只要'bluegreen'保持设置为'nonprod',这里的东西应该是稳定的。 –