如何用Pulumi为多子域名ACM证书创建DNS验证Route53记录?
解决Pulumi中ACM多SAN证书DNS验证记录的创建问题
核心问题
AWS ACM证书的domain_validation_options是Pulumi的Output对象,无法直接用常规Python循环遍历,必须通过apply方法访问其内部的实际值,才能找到指定域名的验证条目并创建Route53记录。
分步实现代码
1. 导入依赖模块
import pulumi import pulumi_aws as aws
2. 创建包含多SAN的ACM证书
# 创建带多个通配符SAN的ACM证书 cert = aws.acm.Certificate("multi-san-cert", domain_name="*.mydomain.tld", subject_alternative_names=[ "*.subdomain01.mydomain.tld", "*.api.focussheet.dev" # 需要单独验证的目标域名 ], validation_method="DNS" )
3. 获取目标域名的Route53托管区
# 替换为你的Route53托管区ID或通过名称查找 zone = aws.route53.Zone.get("api-zone", "ZXXXXXXXXXXXXXX")
4. 定义函数提取目标域名的验证参数
def get_target_validation_params(validation_options, target_domain): # 遍历验证选项,匹配目标域名 for option in validation_options: if option["domain_name"] == target_domain: return { "name": option["resource_record_name"], "type": option["resource_record_type"], "value": option["resource_record_value"] } raise ValueError(f"未找到{target_domain}对应的验证条目")
5. 用apply处理Output并创建验证记录
# 提取目标域名的验证记录参数(返回Output对象) target_validation_params = cert.domain_validation_options.apply( lambda opts: get_target_validation_params(opts, "*.api.focussheet.dev") ) # 创建Route53 DNS验证记录 validation_record = aws.route53.Record("api-cert-validation", zone_id=zone.id, name=target_validation_params.apply(lambda p: p["name"]), type=target_validation_params.apply(lambda p: p["type"]), records=[target_validation_params.apply(lambda p: p["value"])], ttl=60 )
6. 导出关键信息
pulumi.export("cert_arn", cert.arn) pulumi.export("validation_record_fqdn", validation_record.fqdn)
批量创建所有SAN的验证记录(可选)
如果需要为所有SAN域名自动创建验证记录,可通过Output.all结合批量创建逻辑实现:
def batch_create_records(validation_options, zone_id): records = [] for idx, opt in enumerate(validation_options): record = aws.route53.Record(f"cert-validation-{idx}", zone_id=zone_id, name=opt["resource_record_name"], type=opt["resource_record_type"], records=[opt["resource_record_value"]], ttl=60 ) records.append(record) return records # 同时传入验证选项列表和托管区ID(均为Output) all_validation_records = pulumi.Output.all(cert.domain_validation_options, zone.id).apply( lambda args: batch_create_records(args[0], args[1]) ) pulumi.export("all_validation_records", [r.fqdn for r in all_validation_records])
关键说明
apply方法是处理Pulumi Output对象的核心:它会在Output的实际值就绪后执行传入的函数,避免直接遍历未解析的Output对象- 所有依赖Output值的资源属性,都需要通过
apply或Output.all来获取实际值,确保Pulumi的依赖图正确构建 - 如果验证条目查找失败,会抛出ValueError,可根据需要添加异常处理逻辑
内容的提问来源于stack exchange,提问作者ssc
相关产品推荐
相关产品推荐

