問題
aws_acm_certificate.domain_validation_optionsは、v2系のProviderでは A list of attributes ~
とのことでリストが返却されていましたが、v3系では Set of domain validation objects ~
の示すようにオブジェクトのセットが返却されるようになり、 こちらの記事などで紹介されているように、リストとしてそのまま走査して値を設定することができなくなった模様です
一般的なプログラミング言語と同様、セットは順序を持たないから走査できない...的な考え方からでしょうか?
domain_validation_optionsのイメージ
Outputs:
domain_validation_options = [
{
"domain_name" = "example.com"
"resource_record_name" = "_xxxxx.example.com."
"resource_record_type" = "CNAME"
"resource_record_value" = "_yyyyy.zzzzz.acm-validations.aws."
},
]
エラーのイメージ
Error: Invalid index
on ./xxx/route53-record.tf line 17, in resource "aws_route53_record" "domain_validation":
17: name = lookup(aws_acm_certificate.example.domain_validation_options[count.index], "resource_record_name")
|----------------
| aws_acm_certificate.example.domain_validation_options is set of object with 1 element
| count.index is 0
This value does not have any indices.
解法
これについて、Terraform v0.12系で利用できるfor_eachとfor式を使うと、いい感じできたので備忘録です✍️
for_eachはlist
以外にもmap
を走査することができるため、forで変換してあげて渡すとエラーとならず参照できます
route53-record.tf
resource "aws_route53_record" "domain_validation" {
# domain_name をキーにしたmapに変換する
for_each = { for el in aws_acm_certificate.example.domain_validation_options : el.domain_name => el }
# 値はeach.valueで参照できる
name = each.value.resource_record_name
type = each.value.resource_record_type
records = [each.value.resource_record_value]
zone_id = aws_route53_zone.example.zone_id
ttl = 30
}
従来の書き方より冗長さが減って、スマートな感じがしますね...!
参考
というか以下に書いてある通りのことです...