如何通过循环从不同ACM证书创建对应数量的R53记录?
解决Terraform中基于ACM证书批量创建Route53验证记录的问题
我需要基于2个不同的ACM证书创建对应的Route53验证记录,目前已经通过for_each遍历用户输入成功创建了ACM证书,但在创建R53记录时,尝试了三种循环写法均报错,希望得到基于循环的解决方案,避免编写冗余的单独资源块。
已成功运行的ACM证书代码
locals { custom_domain_api = [ { acm_name_api = join("",["api-",var.app_region,"-",var.application,"-",var.environment,lookup(var.r53_domain,var.environment)]) customdomain_api = join("",["api-",var.app_region,"-",var.application,"-",var.environment,lookup(var.r53_domain,var.environment)]) }, { acm_name_api = join("",["ui-",var.app_region,"-",var.application,"-",var.environment,lookup(var.r53_domain,var.environment)]) customdomain_api = join("",["ui-",var.app_region,"-",var.application,"-",var.environment,lookup(var.r53_domain,var.environment)]) } ] } resource "aws_acm_certificate" "acm_api" { provider = aws.main for_each = { for index, api in local.custom_domain_api: api.customdomain_api => api } domain_name = each.value.acm_name_api validation_method = "DNS" tags = merge( {NAME = each.value.acm_name_api}, local.common_tags ) }
尝试过的错误R53记录写法
#1
resource "aws_route53_record" "acm_r53" { for_each = { for dvo in flatten(aws_acm_certificate.acm_api[*].domain_validation_options.domain_name) : dvo.domain_name => { name = dvo.resource_record_name record = dvo.resource_record_value } } zone_id = local.r53_zoneid name = each.value.name type = "CNAME" ttl = "300" records = [each.value.record] }
#2
resource "aws_route53_record" "acm_r53" { for_each = aws_acm_certificate.acm_api[each.key].domain_validation_options zone_id = local.r53_zoneid name = tolist(aws_acm_certificate.acm_api[each.key].domain_validation_options).resource_record_name type = "CNAME" ttl = "300" records = [tolist(aws_acm_certificate.acm_api[each.key].domain_validation_options).resource_record_value] }
#3
resource "aws_route53_record" "acm_r53" { for_each = aws_acm_certificate.acm_api[each.key].domain_validation_options zone_id = local.r53_zoneid name = tolist(aws_acm_certificate.acm_api[each.key].domain_validation_options)[0].resource_record_name type = "CNAME" ttl = "300" records = [tolist(aws_acm_certificate.acm_api[each.key].domain_validation_options)[0].resource_record_value] }
正确的批量创建方案
问题核心在于之前的写法未正确处理domain_validation_options的结构:每个ACM证书的该字段是列表类型,且for_each表达式中无法提前引用each.key。以下是正确的嵌套循环写法:
resource "aws_route53_record" "acm_r53" { for_each = { # 嵌套遍历:先遍历所有ACM证书,再遍历每个证书的验证选项 for cert_key, cert in aws_acm_certificate.acm_api : for dvo in cert.domain_validation_options : # 用「域名-记录名称」作为唯一键,避免重复 "${dvo.domain_name}-${dvo.resource_record_name}" => { zone_id = local.r53_zoneid name = dvo.resource_record_name type = dvo.resource_record_type record = dvo.resource_record_value } } zone_id = each.value.zone_id name = each.value.name type = each.value.type ttl = 300 records = [each.value.record] }
写法说明
- 嵌套
for循环:先遍历所有已创建的ACM证书,再遍历每个证书下的DNS验证选项 - 唯一键生成:用
${dvo.domain_name}-${dvo.resource_record_name}确保每个R53记录的键唯一,防止Terraform报错 - 动态提取字段:直接从
dvo(domain_validation_options的元素)中获取记录名称、类型和值,无需额外类型转换
内容的提问来源于stack exchange,提问作者forevernewbie
相关产品推荐
相关产品推荐

