【问题标题】:In terraform, how do I output an aws_route53_record alias value?在 terraform 中,如何输出 aws_route53_record 别名值?
【发布时间】:2020-11-17 08:11:25
【问题描述】:

Terraform v0.12.x

我正在创建一个 AWS Route53 记录,就像这样,它的创建没有问题。

data "aws_route53_zone" "zone" {
  name         = "my.domain.com."
  private_zone = true
}

resource "aws_route53_record" "record" {
  zone_id = data.aws_route53_zone.zone.zone_id
  name    = "${var.record_name}.${data.aws_route53_zone.zone.name}"
  type    = "A"
  alias {
    name                   = var.alias_record
    zone_id                = var.alias_zone_id
    evaluate_target_health = false
  }
}

现在我想输出别名的值,我试过了

output "alias_name" {
  value = aws_route53_record.record.alias.name
}

output "alias_name" {
  value = aws_route53_record.record.alias["name"]
}

但得到错误

Block type "alias" is represented by a set of objects, and set elements do not
have addressable keys. To find elements matching specific criteria, use a
"for" expression with an "if" clause.

正确的语法是什么?

【问题讨论】:

    标签: amazon-web-services terraform terraform-provider-aws


    【解决方案1】:

    alias 是一组对象和集合are

    没有任何辅助标识符或排序的唯一值的集合。

    所以你不能索引它们。因此,在您的情况下输出您可以使用的别名值:

    output "alias_name" {
      value = aws_route53_record.record.alias.*.name
    }
    
    # or
    
    output "alias_name2" {
      value = aws_route53_record.record.alias[*].name
    }
    

    【讨论】:

    • 谢谢,这是有道理的,而且有效。但是,我可以按照错误消息的提示使用forif 语句吗?如果有怎么办?
    【解决方案2】:

    此处返回的错误消息 Terraform 是一个通用错误消息,它为表示为一组对象的所有块类型返回一个通用错误消息,因此它为您提供了一些基于其值或嵌套值选择集合元素的一般建议。例如:

    output "example" {
      # Select the first element from the
      # set whose name is "foo".
      value = [
        for a in aws_route53_record.record.alias : a
        if a.name == "foo"
      ][0]
    }
    

    该建议实际上并不适合您在此处遇到的特定问题,因为您不是“查找符合特定条件的元素”,而只是尝试选择您知道自己编写的一个元素,因为您只静态定义了无论如何,一个alias 块,所以你知道它会一直存在并且永远是正确的。

    为此,一种选择是使用the tolist function 将集合显式转换为列表。文档警告说,结果元素不会按任何特定顺序排列,但是当只有一个元素时,该元素只能有一个顺序,因此这是安全的:

    output "example" {
      # Select the first element from the
      # set whose name is "foo".
      value = tolist(aws_route53_record.record.alias)[0].name
    }
    

    如果底层 API 认为对象是无序的并且没有特定的唯一标识符,则提供者通常会为特定的块类型使用集合表示。不幸的是,结果使用起来不太方便,但是使用这种对底层行为的准确建模避免了配置可能首先工作但后来如果远程 API 开始以不同(任意)顺序返回项目时行为不端的问题。

    这个alias 块的集合选择有点奇怪,因为它被定义为只允许零个或一个块;我怀疑这是供应商为了向后兼容而保留的历史设计怪癖。

    【讨论】:

      【解决方案3】:

      结合 Marcin 和 Martin 的答案(感谢两者),这就是我最终使用的答案

      output "alias_name" {
        value =  tolist(aws_route53_record.record.alias.*.name)[0]
      }
      

      Marcin 给出的答案

      alias_name = [
        "my-record.domain.com",
      ]
      

      虽然马丁的回答给出了

      alias_name = {
        "evaluate_target_health" = false
        "name" = "my-record.domain.com"
        "zone_id" = "Z1234ABCDE"
      }
      

      但是结合我上面的两个答案给出了

      alias_name = my-record.domain.com
      

      【讨论】:

      • 对不起...我意识到回头看我忘记包含 .name 属性的答案,因此它确实导出了整个对象而不仅仅是名称。我现在已经编辑了我的答案以包含 .name,但我在答案中所做的在功能上与您在您的答案中所做的相同,只是写的有点不同。
      猜你喜欢
      • 2020-04-22
      • 2020-12-14
      • 2022-01-09
      • 2017-12-24
      • 2022-01-19
      • 2020-12-07
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多