terraform-provider-aws 数据源 aws_eks_clusters:全量枚举一个 AWS 区域的 EKS 集群名称
2026/9/18 15:36:50 网站建设 项目流程

terraform-provider-aws 数据源 aws_eks_clusters:全量枚举一个 AWS 区域的 EKS 集群名称

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

本篇技术文章围绕 Terraform AWS Provider 的数据源aws_eks_clusters展开:介绍它的适用场景、完整的 HCL 用法、参数与属性定义,并结合internal/service/eks包下的源码与验收测试,深入讲解它如何通过 AWS SDK for Go v2 的分页器(Paginator)遍历整个区域的 EKS 集群。读完后,你将能够用该数据源在 Terraform 配置中动态发现区域内的所有 EKS 集群,并理解其背后的分页迭代实现与测试验证方式。

数据源定位:从“名称列表”到“集群详情”

aws_eks_clusters是一个列表型数据源(list-type data source),其官方描述为 “Retrieve EKS Clusters list”(检索 EKS 集群列表)。它解决的问题是:当你不知道当前区域里存在多少个 EKS 集群、或不想手工维护集群名称清单时,可以用一条data块直接枚举出区域内全部集群的名称集合,再基于这些名称驱动其他资源或数据源(for_each)逐个获取详情。

与之对应的单集群数据源是aws_eks_cluster(需要预先指定name)。官方文档给出的典型用法正是两者的组合:先用aws_eks_clusters拿到名称集合,再用for_each对每个名称实例化aws_eks_cluster拉取完整详情。

示例用法

官方文档(website/docs/d/eks_clusters.html.markdown)给出的完整示例如下,可直接复制使用:

data "aws_eks_clusters" "example" {} data "aws_eks_cluster" "example" { for_each = toset(data.aws_eks_clusters.example.names) name = each.value }

要点说明:

  • data "aws_eks_clusters" "example" {}不需要任何必填参数,空块即表示“列出当前 provider 配置区域下的全部集群”;
  • names的类型是Set(无序集合),因此在 HCL 中先经toset(...)显式转换为 set 类型,再传给for_each,保证每个集群只实例化一次;
  • 内层data.aws_eks_cluster.example会为集合中的每个名称创建一个实例,最终data.aws_eks_cluster.example[<name>]即对应单个集群的完整属性(状态、Kubernetes 版本、vpc_config 等,详见aws_eks_cluster数据源文档)。

这一“列表数据源 + for_each 详情数据源”的模式,是该仓库所有列表型数据源的通用消费方式。

参数参考(Argument Reference)

该数据源支持的参数很少,官方文档只列出:

参数必填说明
region否(Optional)查询的 AWS 区域。缺省时使用 provider 配置中设置的 Region。

从源码看(clusters_data_source.go),dataSourceClusters()的 schema 中只显式声明了一个属性namesnames.AttrNamesTypeSetComputed,元素为字符串),没有任何可配置的过滤参数(如名称前缀、标签过滤都不支持)。region参数由 provider 层面的区域解析机制统一处理,Read函数通过c.Region(ctx)读取当前生效区域——这正是文档中“Defaults to the Region set in the provider configuration”的实现来源。因此:

  • 想查询其他区域的集群,需要在data块上显式写region = "eu-west-1"(由 provider 的 region 逻辑注入到客户端);
  • 若需要按标签、名称前缀等条件筛选,只能在拿到names之后,在 HCL 层用setintersectsetintersection等集合函数自行过滤,数据源本身不提供服务端过滤。

属性参考(Attribute Reference)

官方文档列出了除参数之外导出的两个属性:

属性说明
idAWS Region(即当前 provider 配置的 AWS 区域名称,例如us-east-1)。
namesSet,区域内所有 EKS 集群的名称集合。

关于id的取值逻辑可以直接在源码中确认:clusters_data_source.go 中执行d.SetId(c.Region(ctx)),即把区域字符串作为 Terraform state 中该数据源的id。这是一种刻意的设计:数据源没有任何服务端资源 ID 可用,用区域标识 id 可以让同一区域多次 plan 之间保持 id 稳定(只要区域不变,state 就不会出现无意义的 diff)。

names的写入则在同文件第 49 行d.Set(names.AttrNames, clusters),其中clusters是经过分页收集后的[]string切片,最终在 state 中表现为无序字符串集合。

源码实现:分页迭代与错误传播

核心 Read 函数

dataSourceClustersRead(clusters_data_source.go)的完整流程只有三步:

  1. 从 provider 元数据取得 EKS 客户端:c.EKSClient(ctx)
  2. 调用tfslices.CollectWithError(listClusters(ctx, conn, &input))一次性收集所有分页的集群名称;出错则通过sdkdiag.AppendFromErr转为 Terraform Diagnostics;
  3. 设置idnames

这里有两个值得注意的实现细节:

  • 传入的input是一个空的eks.ListClustersInput——再次印证该 API 调用不带任何过滤条件,返回的是区域内的全量集群名称;
  • 数据源文件头部的@SDKDataSource("aws_eks_clusters", name="Clusters")注解用于代码生成(见 service_package_gen.go 中的Factory: dataSourceClusters注册项),保证数据源名称、常量与生成代码保持同步。

分页收集器:listClusters 迭代器

真正调用 AWS API 的是listClusters函数(cluster_list.go),它返回一个 Go 1.23 风格的iter.Seq2[string, error]迭代器序列:

func listClusters(ctx context.Context, conn *eks.Client, input *eks.ListClustersInput) iter.Seq2[string, error] { return func(yield func(string, error) bool) { pages := eks.NewListClustersPaginator(conn, input) for pages.HasMorePages() { page, err := pages.NextPage(ctx) if err != nil { yield(inttypes.Zero[string](), fmt.Errorf("listing EKS Clusters: %w", err)) return } for _, item := range page.Clusters { if !yield(item, nil) { return } } } } }

关键点:

  • 自动分页eks.NewListClustersPaginator是 AWS SDK for Go v2 的分页器,ListClustersAPI 单页最多返回 100 个结果,当区域内集群超过单页容量时,该循环会透明地跟随NextToken取完所有页。对用户而言names永远是完整的;
  • 错误包装:分页失败时错误被包装为listing EKS Clusters: <原始错误>并经由yield的 error 通道传出,由CollectWithError接收后变成 Terraform 诊断信息,便于排障;
  • 提前终止支持if !yield(item, nil) { return }让调用方可以中途停止消费,不过数据源场景下CollectWithError会消费到底,收集全部名称。

CollectWithError定义在 internal/slices/slices.go,它把iter.Seq2[E, error]序列物化为切片,是仓库中“迭代器 → 集合”的通用转换工具。

与新版 list resource 的共享实现

值得注意的是,listClusters同时被两处复用:

  1. 本数据源aws_eks_clusters(SDKv2 风格,只导出名称集合);
  2. 框架层的list resourceaws_eks_cluster(cluster_list.go 中@SDKListResource("aws_eks_cluster")),它通过yield逐条产出集群,并在request.IncludeResource时进一步调用findClusterByName拉取完整集群属性做展平(flatten)。

也就是说,仓库内部“只列名称”和“列出带详情资源”两条路径共用同一个分页迭代器,避免了重复实现分页逻辑。对于希望以 Terraform 框架原生的 list resource 方式消费集群列表的场景,可以参考仓库文档 docs/list-resources.md。

验收测试如何验证该数据源

验收测试TestAccEKSClustersDataSource_basic位于 clusters_data_source_test.go,其验证逻辑简洁但有代表性:

func TestAccEKSClustersDataSource_basic(t *testing.T) { ctx := acctest.Context(t) rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) dataSourceResourceName := "data.aws_eks_clusters.test" acctest.ParallelTest(ctx, t, resource.TestCase{ // ... Steps: []resource.TestStep{ { Config: testAccClustersDataSourceConfig_basic(rName), Check: resource.ComposeTestCheckFunc( acctest.CheckResourceAttrGreaterThanValue(dataSourceResourceName, "names.#", 0), ), }, }, }) }

测试配置(同文件第 35–41 行)先用testAccClusterConfig_basic创建了一个真实集群,再声明:

data "aws_eks_clusters" "test" { depends_on = [aws_eks_cluster.test] }

这里depends_on保证数据源读取发生在集群创建之后,随后用CheckResourceAttrGreaterThanValue(..., "names.#", 0)断言集合非空——即“刚创建的集群一定出现在names里”。names.#正是 Set 类型的元素个数属性。该测试运行需要真实的 AWS 凭据与区域环境,可参阅仓库文档 docs/running-and-writing-acceptance-tests.md 了解验收测试的执行方式。

适用前提与使用限制

基于仓库当前实现,使用该数据源时需注意:

  • 区域粒度:它枚举的是 provider 当前(或显式指定的)单个区域内全部 EKS 集群,不会跨区域;查询多区域需为每个区域声明 provider 别名或显式region
  • 无过滤能力:不支持名称前缀、状态、标签等任何服务端过滤条件,筛选只能在 HCL 层对names做集合运算;
  • 只含名称:本数据源只返回集群名称,不包含状态、版本、endpoint 等字段;获取详情请配合aws_eks_cluster数据源,或采用框架 list resourceaws_eks_cluster
  • 权限要求:执行该读取需要调用者具备eks:ListClusters权限。

关键文件索引

文件作用
website/docs/d/eks_clusters.html.markdownaws_eks_clusters数据源官方文档(本文主体来源)
internal/service/eks/clusters_data_source.go数据源 schema 定义与 Read 实现
internal/service/eks/cluster_list.go分页迭代器listClusters与 list resource 实现
internal/service/eks/clusters_data_source_test.go验收测试
internal/service/eks/service_package_gen.go数据源在 service package 中的工厂注册
internal/slices/slices.go迭代器切片收集器CollectWithError
docs/list-resources.md框架 list resource 设计与使用文档
docs/add-a-new-datasource.md新增数据源的开发指南

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

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

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

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

立即咨询