使用 terraform 0.12+ 计算输出变量

rix*_*rix 6 terraform terraform0.12+

我有条件地创建一个带有计数的资源:

resource "aws_kms_key" "this" {
  count       = var.create_kms_key == true ? 1 : 0
  ...
}
Run Code Online (Sandbox Code Playgroud)

那么我如何有条件地输出这个资源的值?我试过玩,Terraform 似乎自相矛盾

首先它告诉我在输出中使用计数。

For example, to correlate with indices of a referring resource, use:
    aws_kms_key.this[count.index]
Run Code Online (Sandbox Code Playgroud)

然后当我尝试它时,它说我不能使用计数。

The "count" object can be used only in "resource" and "data" blocks, and only
when the "count" argument is set.
Run Code Online (Sandbox Code Playgroud)

以前我们可以做类似下面的事情,但现在这会触发我之前发布的计数错误。

output "kms_key_arn" {
    value = aws_kms_key.this.*.arn
}
Run Code Online (Sandbox Code Playgroud)

知道现在这是如何工作的吗?

谢谢,

Mar*_*ins 8

count为资源设置时,对该资源的引用然后返回对象列表而不是单个对象,因此我们需要在编写其他表达式时考虑到这一点。

在您的情况下,该列表可以有零个或一个元素,因此我们必须在引用它的任何表达式中处理这两种情况。

要编写从该资源传播属性的输出,我们需要决定在列表为空的情况下将返回什么。例如,null在这种情况下,我们可以选择将输出设置为:

output "kms_key_arn" {
    value = concat(aws_kms_key.this.*.arn, [null])[0]
}
Run Code Online (Sandbox Code Playgroud)

这里的技术是将具有零或一个元素的列表更改为具有一或两个元素的列表,然后取第一个元素。该concat函数可能返回的内容有两种可能性:

["arn:aws:....", null]
[null]
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,使用 取第零个元素是有效的[0]。在第二种情况下,它将选择null作为结果。


如果您有其他资源也以 为条件var.create_kms_key,则此方法有一个变体:

resource "aws_kms_key" "example" {
  count = var.create_kms_key ? 1 : 0

  # ...
}

resource "anything_else" "example" {
  count = length(aws_kms_key.example) # only if KMS key is created

  any_argument = aws_kms_key.example[count.index].arn
}
Run Code Online (Sandbox Code Playgroud)

这个变体依赖于这样一个事实,即这两个资源具有相同的值count,因此我们可以count.index在第二个资源中使用,以便与第一个资源的实例相关联。count.index只能在count已设置的资源中使用,但在这种特殊情况下它设置,并且因为我们设置count了其他资源的长度,所以我们知道所有count.index值都将在该资源的对象列表的范围内。