You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过循环从不同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]
}

写法说明

  1. 嵌套for循环:先遍历所有已创建的ACM证书,再遍历每个证书下的DNS验证选项
  2. 唯一键生成:用${dvo.domain_name}-${dvo.resource_record_name}确保每个R53记录的键唯一,防止Terraform报错
  3. 动态提取字段:直接从dvo(domain_validation_options的元素)中获取记录名称、类型和值,无需额外类型转换

内容的提问来源于stack exchange,提问作者forevernewbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:56:03