字符串的Terraform插值语法

时间:2018-03-08 10:11:01

标签: amazon-web-services terraform

我正在尝试使用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]}

3 个答案:

答案 0 :(得分:3)

经过多次试验和错误之后,解决方案就是:

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
}

答案 1 :(得分:0)

语法为:

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

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

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

答案 2 :(得分:0)

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

你几乎已经进行了初步尝试,只需将它强制进入一个列表,就像你第二次尝试一样,并将splat放在正确的位置:

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

请注意,这是使用splat indexing获取所有资源,然后使用list[index] syntax获取索引。也可以像这样使用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)}"会在"a"时返回"${var.foo_list[3]}"而在索引超出范围异常的情况下会返回错误。