深入解析 Terraform AWS Provider 的 aws_elb 数据源:读取 Classic Load Balancer 配置
2026/9/19 5:08:05 网站建设 项目流程

深入解析 Terraform AWS Provider 的 aws_elb 数据源:读取 Classic Load Balancer 配置

【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws

aws_elb是 terraform-provider-aws 中用于读取 AWS Classic Elastic Load Balancer(简称 Classic ELB,下称 ELB)运行时配置的数据源。当模块以负载均衡器名称作为输入、需要进一步获取其安全组、子网、监听器、健康检查与 DNS 信息时,用它替代硬编码值是最直接的方式。读完本篇,你将掌握该数据源的完整参数与全部导出属性,理解其底层 AWS API 调用链与源码实现细节,并能在模块化 Terraform 工程中正确使用它。

数据源定位:Classic ELB 还是 ALB/NLB?

aws_elb数据源专门面向 AWS 于 2015 年前后发布的 "Classic" Elastic Load Balancer(第一代负载均衡服务)。在 AWS 推出 Application Load Balancer(ALB)与 Network Load Balancer(NLB)之后,Terraform 社区通常将它们统称为 "v2" 负载均衡器。如果你需要读取的是 ALB 或 NLB 的信息,应改用aws_lb数据源;aws_elb仅适用于 Classic ELB。

数据源文档开篇即给出典型动机:

当一个模块将 LB 作为输入变量接收、需要据此确定其关联的安全组等信息时,该数据源非常有用。

例如,一个应用模块接收lb_name字符串作为输入,内部通过aws_elb数据源拿到该 ELB 的全部运行时属性,从而推导出安全组、可用区、子网等依赖关系,而无需在调用方与模块之间层层传递这些值。

最小可用示例

数据源的全部使用方式围绕name参数展开。文档给出的最小示例:

variable "lb_name" { type = string default = "" } data "aws_elb" "test" { name = var.lb_name }

执行terraform planterraform apply时,Provider 会调用 AWS 的DescribeLoadBalancersDescribeLoadBalancerAttributesAPI,按name精确匹配一个 Classic ELB,并将结果写入状态。随后在配置中即可引用data.aws_elb.test.dns_namedata.aws_elb.test.security_groups等导出属性。

若指定的名称不存在,数据源读取会直接失败并返回形如reading ELB Classic Load Balancer (...) : ...的错误(对应源码中的错误包装逻辑,见 load_balancer_data_source.go),因此name对应的 ELB 必须真实存在。

Argument Reference:参数说明

数据源支持以下参数:

参数必填说明
name负载均衡器的唯一名称。底层对应 AWS API 的LoadBalancerName,用于精确匹配。
region数据源所在的 AWS 区域,默认使用 Provider 配置中设置的区域。

注意一个值得说明的细节:虽然文档层面列出了region参数,但从当前仓库中数据源的 schema 定义(load_balancer_data_source.go)看,schema 中只显式声明了name为必填属性,其余均为Computed。实际读取时使用的是 Provider 连接(meta.(*conns.AWSClient).ELBClient(ctx))所对应的区域——也就是说区域由 Provider 配置统一决定,这也与"Defaults to the Region set in the provider configuration"的说明一致。

Attribute Reference:完整导出属性

数据源文档明确说明:返回的属性与aws_elb资源完全一致。结合资源文档与数据源源码 schema,data.aws_elb.*完整导出以下属性:

基础标识与网络属性

属性类型说明
idstringELB 的名称(与name相同)。
namestringELB 的名称。
arnstringELB 的 Amazon Resource Name。
dns_namestringELB 的 DNS 名称,用于接入流量解析。
zone_idstringELB 的规范 hosted zone ID,常配合 Route 53 Alias 记录使用。
internalbool是否为内网(internal)ELB。
availability_zonesset(string)ELB 服务流量的可用区列表(EC2-classic 场景)。
subnetsset(string)ELB 挂载的子网 ID 列表(VPC 场景)。
security_groupsset(string)分配给 ELB 的安全组 ID 列表。
instancesset(string)ELB 后端实例池中的实例 ID 列表。

监听器与健康检查

属性类型说明
listenerset监听器配置块列表,每个块包含instance_portinstance_protocollb_portlb_protocolssl_certificate_id
health_checklist健康检查配置块,包含healthy_thresholdunhealthy_thresholdtargetintervaltimeout

行为特性与安全属性

属性类型说明
cross_zone_load_balancingbool是否开启跨可用区负载均衡。
idle_timeoutint连接允许空闲的秒数。
connection_drainingbool是否开启连接排空。
connection_draining_timeoutint连接排空允许的秒数。
desync_mitigation_modestringHTTP 反同步缓解模式,取值monitordefensive(默认)、strictest
access_logslist访问日志配置块,包含bucketbucket_prefixintervalenabled
source_security_groupstring可用于后端应用实例入站规则的安全组名称(Classic 或默认 VPC 场景)。
source_security_group_idstring后端应用实例入站规则使用的安全组 ID(仅 VPC 中的 ELB 可用)。
tags/tags_allmap资源标签映射。tags_all包含从 Providerdefault_tags继承的标签。

这些导出属性与资源的对应关系完全一致:例如资源侧ssl_certificate_id仅在lb_protocol为 HTTPS 或 SSL 时合法,数据源读取的listener块也会原样呈现这些字段。

源码级剖析:数据源是如何读取 ELB 的

数据源注册与 Schema

数据源在 load_balancer_data_source.go 中通过注解// @SDKDataSource("aws_elb", name="Classic Load Balancer")声明,由 Provider 的代码生成机制注册到aws_elb地址。其实现是典型的 Plugin SDK v2schema.ResourcenameRequired,其余 20 余个字段全部标记为Computed,意味着该数据源只读、不做任何写操作。

读取流程与 API 调用链

核心读取逻辑dataSourceLoadBalancerRead(load_balancer_data_source.go)按以下顺序工作:

  1. 按名称查找 ELB:调用findLoadBalancerByName(load_balancer.go),其内部发起DescribeLoadBalancers请求,并将AccessPointNotFoundException映射为retry.NotFoundError——这是 Provider 把"资源不存在"统一表达为 NotFound 的标准做法,随后通过tfresource.AssertSingleValueResult断言唯一结果。
  2. 读取属性配置:发起DescribeLoadBalancerAttributes请求,取得LoadBalancerAttributes(访问日志、连接排空、跨可用区、空闲超时、反同步缓解等)。
  3. 手工构造 ARN:通过arn.ARN结构体拼接elasticloadbalancing服务的 ARN,资源段为loadbalancer/<名称>,分区、区域、账号 ID 均取自 Provider 客户端上下文。
  4. 补齐安全组 ID:AWS 的DescribeLoadBalancers响应只返回源安全组名称与属主,不返回安全组 ID。源码在lb.VPCId存在时,会进一步调用 EC2 客户端的FindSecurityGroupByNameAndVPCIDAndOwnerID反向查找source_security_group_id(load_balancer_data_source.go)。
  5. 处理访问日志的"不可删除"语义:注释明确指出 AWS API 不允许删除access_logs、只能禁用它。源码通过d.GetChange("access_logs")对比配置与远端状态,只有配置中存在访问日志块且远端已启用时才写入状态,从而避免把外部 API 创建的日志配置误判为 drift(相关历史 issue 详见源码注释)。
  6. 读取标签:调用listTags获取标签并通过IgnoreAWS().IgnoreConfig(ignoreTagsConfig)过滤后写入tags
  7. 回填健康检查:健康检查只有一个,lb.HealthCheck.Target非空时通过flattenHealthCheck写入。

字段展开函数

数据源用到的展开函数集中在 flex.go:

  • flattenAccessLog(L17-L42):将 API 的AccessLog对象映射为bucketbucket_prefixintervalenabled四个字段;
  • flattenHealthCheck(L56-L73):映射healthy_thresholdunhealthy_thresholdtargettimeoutinterval
  • flattenInstances(L75-L79):把 API 的Instance列表投影为实例 ID 字符串列表;
  • flattenListenerDescriptions(L132 起):将每个监听器映射为instance_portinstance_protocollb_portlb_protocolssl_certificate_id,并统一转为小写协议名。

desync_mitigation_mode这类位于AdditionalAttributes中的扩展属性,则在读取循环中按常量elb.http.desyncmitigationmode(定义于 consts.go)逐一匹配后写入状态。

实测验证:数据源如何被测试覆盖

仓库为数据源提供了完整的验收测试TestAccELBLoadBalancerDataSource_basic(load_balancer_data_source_test.go)。该测试先创建一个完整的 VPC、两个子网、一个安全组与一个内部 ELB,再通过data "aws_elb" "test" { name = aws_elb.test.name }读取它,并断言:

  • cross_zone_load_balancinginternal等布尔属性与预期一致;
  • idle_timeout精确等于资源侧的30
  • subnets.#security_groups.#数量正确;
  • desync_mitigation_mode默认值为defensive
  • 标签tags.Nametags.TestName完整回传;
  • dns_namezone_id非空;
  • 数据源的arn与资源侧aws_elb.test.arn完全一致(TestCheckResourceAttrPair)。

测试中特意将 ELB 名称控制在 32 个字符以内(代码注释:ELB name 必须小于 32 字符),这正是 Classic ELB 的命名约束。这段测试既是对数据源行为的权威验证,也是"模块内通过数据源反查 ELB 属性"这一用法的可直接复制的示例。

实战建议与注意事项

  1. 模块输入用名称而非属性:在模块边界传递lb_name字符串,模块内部用aws_elb数据源展开安全组、DNS、子网等派生属性,可避免模块接口膨胀,也方便对已存在(非 Terraform 管理)的 ELB 做只读集成。
  2. 区分数据源与资源aws_elb资源负责创建与管理 ELB(完整参数见 aws_elb 资源文档),数据源只负责读取。若需要管理而非查询,应使用资源。
  3. source_security_group_id的适用性:该属性仅对 VPC 内的 ELB 生效,且需要额外一次 EC2 API 查询;EC2-classic 场景下应使用source_security_group
  4. 区分 ELB 家族数据源:同目录下还有 aws_elb_hosted_zone_id 与 aws_elb_service_account 两个配套数据源,分别用于获取 ELB 的 Route 53 hosted zone ID 与访问日志写入账号 ID,常与aws_elb组合使用;ALB/NLB 场景请改用 aws_lb 数据源。
  5. 资源属性参照:数据源返回的所有属性与aws_elb资源完全一致,若需了解各属性的取值范围(如desync_mitigation_mode的合法值、ssl_certificate_id的 ECDSA 曲线限制),可直接查阅该资源文档。

小结

aws_elb数据源是 Classic ELB 生态中"只读集成"的关键入口:以name为唯一必填参数,返回与资源侧完全一致的完整属性集。其底层由DescribeLoadBalancers+DescribeLoadBalancerAttributes两条 AWS API 驱动,辅以 EC2 安全组反查、ARN 手工拼接、标签过滤与访问日志语义处理等细节实现,并由验收测试严格保证行为正确。无论是对既有 ELB 做只读查询,还是在模块化工程中传递 LB 依赖,它都是可靠且标准的选择。

【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询