字符串的 Terraform 插值语法

Terraform interpolation syntax for string

我正在尝试使用 terraform 为多个 DNS 记录制作 SSL 证书,遵循此处的文档:https://www.terraform.io/docs/providers/aws/r/acm_certificate_validation.html

对于 Route 53 记录给出了这个例子:

resource "aws_route53_record" "cert_validation" {
  name = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl = 60
}

名称和类型中的 0 指的是他们提供的单个 DNS 条目。如果我将几个 subject_alternative_names 添加到 aws_acm_certificate 并添加几个手动 aws_route53_record 并将 0 替换为 1 2 等,它的工作方式我想。

我的问题是,我可以使用 Terraform 的 count 一次完成此操作吗?我用 count = 5:

试过这两件事
name = "${aws_acm_certificate.cert.domain_validation_options.*.resource_record_name[count.index]}"

这抱怨它得到的是一个字符串而不是一个列表

name = "${aws_acm_certificate.cert.domain_validation_options.count.index.resource_record_name}"

这给了他们相同的名字,只是“5”。

编辑:

设置:

resource "aws_route53_record" "cert_validation" {
    count = 5
    name = "${aws_acm_certificate.cert.domain_validation_options.*.resource_record_name[count.index]}"
    type = "CNAME"
    zone_id = "myzoneid"
    records = ["${aws_acm_certificate.cert.domain_validation_options.*.resource_record_value[count.index]}"]
    ttl = 60
}

错误:

* aws_route53_record.cert_validation: 5 error(s) occurred:

* aws_route53_record.cert_validation[4]: At column 95, line 1: invalid index operation into non-indexable type: TypeString in:

${aws_acm_certificate.cert.domain_validation_options.*.resource_record_value[count.index]}
* aws_route53_record.cert_validation[2]: At column 94, line 1: invalid index operation into non-indexable type: TypeString in:

${aws_acm_certificate.cert.domain_validation_options.*.resource_record_name[count.index]}
* aws_route53_record.cert_validation[3]: At column 94, line 1: invalid index operation into non-indexable type: TypeString in:

${aws_acm_certificate.cert.domain_validation_options.*.resource_record_name[count.index]}
* aws_route53_record.cert_validation[0]: At column 95, line 1: invalid index operation into non-indexable type: TypeString in:

${aws_acm_certificate.cert.domain_validation_options.*.resource_record_value[count.index]}
* aws_route53_record.cert_validation[1]: At column 94, line 1: invalid index operation into non-indexable type: TypeString in:

${aws_acm_certificate.cert.domain_validation_options.*.resource_record_name[count.index]}

语法是:

name = "${element(aws_acm_certificate.cert.domain_validation_options.*.resource_record_name, count.index)}"

也就是说,您正在使用 element(arr, idx) 查找函数来获取感兴趣索引的实际值。

这里有一个有用的 cheat sheet terraform 函数。

aws_route53_record resource records 参数采用字符串列表,因此如果您尝试提供直接字符串,它将失败。

您在第一次尝试时就快完成了,只需要像在第二次尝试时那样将其强制放入列表中,并将 splat 放在正确的位置:

records = ["${aws_acm_certificate.cert.*.domain_validation_options.resource_record_name[count.index]}"]

请注意,这是使用 splat indexing to fetch all the resources and then grabbing the index using the list[index] syntax. It's also possible to use the element(list, index) 语法,如下所示:

records = ["${element(aws_acm_certificate.cert.*.domain_validation_options.resource_record_name, count.index)}"]

第二个语法允许你循环遍历列表,所以如果你有类似的东西:

variable "foo_list" {
  default = [
    "a",
    "b",
    "c",
  ]
}

然后 "${element(var.foo_list, 3)}" 将 return "a" while "${var.foo_list[3]}" while 索引超出范围异常的错误。

经过反复试验,解决方案是这样的:

resource "aws_route53_record" "cert_validation" {
    count = 5
    name = "${lookup(aws_acm_certificate.cert.domain_validation_options[count.index], "resource_record_name")}"
    type = "CNAME"
    zone_id = "myzoneid"
    records = ["${lookup(aws_acm_certificate.cert.domain_validation_options[count.index], "resource_record_value")}"]
    ttl     = 60
}
resource "aws_route53_record" "cert_validation" {
  name = "${aws_acm_certificate.cert.domain_validation_options.*.resource_record_name[0]}"
  type = "${aws_acm_certificate.cert.domain_validation_options.*.resource_record_type[0]}"

  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.*.resource_record_value[0]}"]
  ttl = 60
}

参考:https://github.com/hashicorp/terraform-provider-aws/issues/14447