Terraform中如何对计数型可选资源的属性使用for_each
解决计数型ACM证书的Route53验证记录创建问题
这个场景确实很常见——处理可选的计数型资源,同时要关联创建依赖它的资源。这里的关键是把计数生成的ACM证书列表转换成for_each能处理的映射,并且在证书不存在时自动让Route53资源不创建。
解决方案代码
直接修改你的aws_route53_record.acm_validation资源的for_each表达式,结合flatten和列表遍历处理计数资源的情况:
resource "aws_route53_record" "acm_validation" { for_each = { for dvo in flatten([ for cert in aws_acm_certificate.cert : cert.domain_validation_options ]) : dvo.domain_name => { name = dvo.resource_record_name record = dvo.resource_record_value type = dvo.resource_record_type } } zone_id = data.aws_route53_zone.r53_zone.zone_id name = each.value.name type = each.value.type ttl = 60 records = [each.value.record] allow_overwrite = true }
原理说明
- 处理计数资源的列表特性:
aws_acm_certificate.cert是计数生成的列表(即使count=1也是单元素列表),所以我们先用for cert in aws_acm_certificate.cert遍历这个列表,提取每个证书的domain_validation_options。 - 扁平化处理:
flatten函数会把嵌套的列表(每个证书的验证选项是列表)转换成一维列表。当count=0时,原列表是空的,flatten后仍然是空列表;当count=1时,就得到该证书所有验证选项的集合。 - 构建for_each映射:最后用
for dvo in ...把扁平化后的验证选项转换成以域名为键的映射——for_each接收空映射时,不会创建任何Route53资源;接收有内容的映射时,就会为每个验证选项创建对应的记录。
额外说明
这种方法不需要额外的条件判断(比如length(aws_acm_certificate.cert) > 0),直接利用Terraform的集合特性自动处理“存在/不存在”的情况,代码更简洁可靠。
内容的提问来源于stack exchange,提问作者Nick Bull
相关产品推荐
相关产品推荐

