如何从YAML提取域名生成Terraform可用的SAN证书扁平化列表
解决步骤
1 先修复变量拼写错误
你当前的变量定义中apax_name为拼写错误,需要修正为和YAML配置对应的apex_name,否则会抛出属性不存在的报错:
variable "source_domains" { type = set(object({ apex_name = string records = set(string) })) }
2 按你的使用场景选择对应处理逻辑
场景1:每个顶级域名单独申请一张证书(推荐)
这种方式证书变更影响范围小,不会因为单个域名更新导致所有域名对应的证书都重新签发。
首先通过局部值构造每个顶级域名对应的全量域名集合(自动去重):
locals { apex_domains_map = { for domain in var.source_domains : domain.apex_name => toset(flatten([ domain.apex_name, domain.records ])) } }
修改ACM资源配置即可:
resource "aws_acm_certificate" "cert" { for_each = local.apex_domains_map provider = aws.certificate_region domain_name = each.key subject_alternative_names = sort(each.value) validation_method = "DNS" }
场景2:所有域名合并到同一张证书
如果你的域名总数不超过ACM单张证书100个SAN的阈值,可以用这种方式。
首先通过局部值拍平所有域名并去重:
locals { all_domains = toset(flatten([ for domain in var.source_domains : [ domain.apex_name, domain.records ] ])) }
ACM资源不需要for_each,直接引用整理好的列表即可:
resource "aws_acm_certificate" "cert" { provider = aws.certificate_region # 主域名取第一个顶级域名即可,可根据需求修改 domain_name = element(var.source_domains, 0).apex_name # 自动排除主域名避免重复,ACM也会自动处理重复的SAN项 subject_alternative_names = sort(setsubtract(local.all_domains, [domain_name])) validation_method = "DNS" }
注意事项
- 即使你的
records列表里已经包含了apex_name也不需要额外处理,toset()会自动去重 - AWS ACM单张证书最多支持100个SAN域名,超过阈值必须拆分多张证书
内容的提问来源于stack exchange,提问作者awiechert
相关产品推荐
相关产品推荐

