Terraform AWS Provider 中的 aws_elb_hosted_zone_id 数据源:为 Route 53 Alias 记录获取 ELB Classic 托管区域 ID
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
本指南围绕 terraform-provider-aws 仓库中的aws_elb_hosted_zone_id数据源展开,讲解如何按区域查询 AWS Elastic Load Balancing(ELB Classic)的 HostedZoneId,并将其用于 Route 53 Alias 记录,避免在配置中硬编码区域对应的托管区域 ID。读完本文,你将掌握该数据源的使用姿势、region参数的覆盖规则、返回值id的含义,以及它背后基于源码维护的分区/区域映射表与真实测试验证。
数据源的价值:为什么需要托管区域 ID
在 Route 53 中为 ELB 创建A记录时,Alias 记录要求同时指定负载均衡器的 DNS 名称(dns_name)和它所属的托管区域 ID(zone_id)。ELB 的托管区域 ID 是按区域固定的静态值,例如us-east-1对应Z35SXDOTRQ7X7K、eu-west-1对应Z32O12XQLNTSW2。这些值虽然公开,但分散在 AWS 官方区域表中,手工抄写容易出错,且新增区域时需要人工同步。
aws_elb_hosted_zone_id数据源正是为了解决这一问题:它把「区域 → HostedZoneId」的映射内置在 Provider 中,只需声明数据源并按需传入region,即可在计划阶段解析出正确的托管区域 ID,让 Route 53 Alias 配置可移植、可维护。
快速开始:完整可运行示例
以下示例来自 官方数据源文档,完整展示了「查询托管区域 ID → 配合aws_elb与aws_route53_record建立 Alias 记录」的典型链路:
data "aws_elb_hosted_zone_id" "main" {} resource "aws_route53_record" "www" { zone_id = aws_route53_zone.primary.zone_id name = "example.com" type = "A" alias { name = aws_elb.main.dns_name zone_id = data.aws_elb_hosted_zone_id.main.id evaluate_target_health = true } }配置要点:
aws_route53_record的alias块中,zone_id直接引用数据源的id属性,而不是写死某个区域常量;name取aws_elb.main.dns_name,即 Classic Load Balancer 的 DNS 名称,与数据源返回的托管区域 ID 配套使用;evaluate_target_health = true表示 Alias 记录按目标 ELB 的健康状态参与 DNS 解析。
当 Provider 的默认区域即为负载均衡器所在区域时,aws_elb_hosted_zone_id可省略region参数直接使用,如上例所示。
参数与属性参考
参数(Arguments)
数据源仅支持一个可选参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
region | string | 否 | 需要查询 AWS ELB HostedZoneId 的区域名称;默认使用 Provider 配置 中设置的区域。 |
region的存在使得「负载均衡器区域」与「Provider 默认区域」可以解耦:例如 Provider 配置在us-east-1,但 ELB 部署在eu-west-1时,可通过region = "eu-west-1"单独取数。
属性(Attributes)
数据源导出以下属性:
| 属性 | 说明 |
|---|---|
id | 所选区域的 AWS ELB HostedZoneId 字符串值,也是本数据源唯一有意义的输出。 |
注意:该数据源的 Schema 本身不声明任何字段,region通过 Provider 侧的区域解析注入,id则在 Read 阶段直接写入,属于典型的「仅输出一个 ID」的数据源。
指定区域查询:显式 region 用法
当需要跨区域查询时,显式传入region:
data "aws_elb_hosted_zone_id" "regional" { region = "eu-west-1" } output "elb_hz_id" { value = data.aws_elb_hosted_zone_id.regional.id # => Z32O12XQLNTSW2 }该用法在仓库的 数据源测试 中有直接印证:测试用例testAccHostedZoneIDDataSourceConfig_explicitRegion传入region = "eu-west-1",并断言结果等于Z32O12XQLNTSW2。另一个用例不传region,则断言结果等于HostedZoneIDPerRegionMap[acctest.Region()],即测试运行区域在映射表中对应的值。
源码级实现:区域映射表与读取逻辑
核心映射表
数据源的实现位于 internal/service/elb/hosted_zone_id_data_source.go。文件顶部定义了一个包级变量hostedZoneIDPerRegionMap,以endpoints.<Region>RegionID常量为键、托管区域 ID 为值,覆盖商业分区、中国分区与 GovCloud 分区共 38 个区域:
| 区域 | HostedZoneId |
|---|---|
| af-south-1 | Z268VQBMOI5EKX |
| ap-east-1 | Z3DQVH9N71FHZ0 |
| ap-east-2 | Z02789141MW7T1WBU19PO |
| ap-northeast-1 | Z14GRHDCWA56QT |
| ap-northeast-2 | ZWKZPGTI48KDX |
| ap-northeast-3 | Z5LXEXXYW11ES |
| ap-south-1 | ZP97RAFLXTNZK |
| ap-south-2 | Z0173938T07WNTVAEPZN |
| ap-southeast-1 | Z1LMS91P8CMLE5 |
| ap-southeast-2 | Z1GM3OXH4ZPM65 |
| ap-southeast-3 | Z08888821HLRG5A9ZRTER |
| ap-southeast-4 | Z09517862IB2WZLPXG76F |
| ap-southeast-5 | Z06010284QMVVW7WO5J |
| ap-southeast-6 | Z023301818UFJ50CIO0MV |
| ap-southeast-7 | Z0390008CMBRTHFGWBCB |
| ca-central-1 | ZQSVJUPU6J1EY |
| ca-west-1 | Z06473681N0SF6OS049SD |
| cn-north-1 | Z1GDH35T77C1KE |
| cn-northwest-1 | ZM7IZAIOVVDZF |
| eu-central-1 | Z215JYRZR1TBD5 |
| eu-central-2 | Z06391101F2ZOEP8P5EB3 |
| eu-north-1 | Z23TAZ6LKFMNIO |
| eu-south-1 | Z3ULH7SSC9OV64 |
| eu-south-2 | Z0956581394HF5D5LXGAP |
| eu-west-1 | Z32O12XQLNTSW2 |
| eu-west-2 | ZHURV8PSTC4K8 |
| eu-west-3 | Z3Q77PNBQS71R4 |
| il-central-1 | Z09170902867EHPV2DABU |
| me-central-1 | Z08230872XQRWHG2XF6I |
| me-south-1 | ZS929ML54UICD |
| mx-central-1 | Z023552324OKD1BB28BH5 |
| sa-east-1 | Z2P70J7HTTTPLU |
| us-east-1 | Z35SXDOTRQ7X7K |
| us-east-2 | Z3AADJGX6KTTL2 |
| us-gov-east-1 | Z166TLBEWOO7G0 |
| us-gov-west-1 | Z33AYJ8TM3BH4J |
| us-west-1 | Z368ELLRRE2KJ0 |
| us-west-2 | Z1H1FL5HABSF5 |
源码注释表明该表依据 AWS 官方区域文档维护(// See https://docs.aws.amazon.com/general/latest/gr/elb.html#elb_region.),任何新区域上线都需同步更新此表,这正是把「静态知识」收编进 Provider 的好处。
读取流程
dataSourceHostedZoneIDRead是整个数据源的读取核心(hosted_zone_id_data_source.go):
- 从
meta.(*conns.AWSClient).Region(ctx)取当前生效区域——region参数未指定时即 Provider 默认区域,指定时则为覆盖后的区域; - 在
hostedZoneIDPerRegionMap中按区域名查表; - 命中则调用
d.SetId(v)将映射值写入id属性; - 未命中则通过
sdkdiag.AppendErrorf返回unsupported ELB Region (%s)错误。
可以看出,该数据源不发起任何 AWS API 调用,完全依赖内置静态映射表,因此速度快、无额外成本,也不受 API 权限影响。
数据源注册与区域语义
在 internal/service/elb/service_package_gen.go 中,该数据源被注册为aws_elb_hosted_zone_id,其区域配置使用inttypes.ResourceRegionNoPartitionValidation()。对照 internal/types/service_package.go 的定义,这表示:允许按资源覆盖区域,但覆盖值不校验是否属于当前分区。这正是中国区、GovCloud 等分区能正常取数的基础——例如cn-north-1与us-gov-east-1都能通过映射表返回各自分区的托管区域 ID。
测试验证
hosted_zone_id_data_source_test.go 中的TestAccELBHostedZoneIDDataSource_basic覆盖了两个关键场景:
- 不传
region时,断言id等于HostedZoneIDPerRegionMap[acctest.Region()],即与当前测试区域映射一致; - 显式传
region = "eu-west-1"时,断言id精确等于Z32O12XQLNTSW2。
测试通过tfelb.HostedZoneIDPerRegionMap引用映射表——该变量由 internal/service/elb/exports_test.go 从包内导出仅供测试使用。运行测试的命令为:
make testacc TESTS=TestAccELBHostedZoneIDDataSource_basic PKG=elb实战建议与注意事项
- 优先使用数据源而非硬编码:即使你知道所在区域的 HostedZoneId,也建议用本数据源引用,以便未来区域表更新(如新增区域、调整值)时配置自动跟随 Provider 版本演进;
- 区分 ELB Classic 与 ELB 新版本:
aws_elb_hosted_zone_id面向的是 Classic Load Balancer(aws_elb);如果你使用的是 ALB/NLB(aws_lb),其托管区域 ID 可直接从aws_lb资源或对应数据源的zone_id属性获取,不必使用本数据源; - 关注区域覆盖语义:
region覆盖不校验分区,跨分区取数也能返回结果,但请确保取值符合实际资源所在区域,避免 Alias 指向错误的托管区域; - 识别不可用区域:当请求的区域不在映射表中时,数据源会直接报错
unsupported ELB Region,属于预期的显式失败,便于尽早发现配置错误。
小结
aws_elb_hosted_zone_id是一个体积小巧但非常实用的数据源:它以仓库源码中维护的 38 个区域映射表为数据基础,把「区域 → ELB 托管区域 ID」的静态知识固化进 Provider,配合aws_route53_record的alias块即可完成 Route 53 到 ELB Classic 的稳定解析。无论 Provider 默认区域是否与 ELB 一致,都能通过可选的region参数精确取数,并用单元/验收测试保障映射正确性,是理解 terraform-provider-aws「以数据源消除硬编码」设计思路的典型范例。
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考