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

terraform-provider-aws 数据源 aws_eks_clusters:全量枚举一个 AWS 区域的 EKS 集群名称 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.godataSourceClusters()的 schema 中只显式声明了一个属性namesnames.AttrNamesTypeSet、Computed元素为字符串没有任何可配置的过滤参数如名称前缀、标签过滤都不支持。region参数由 provider 层面的区域解析机制统一处理Read函数通过c.Region(ctx)读取当前生效区域——这正是文档中“Defaults to the Region set in the provider configuration”的实现来源。因此想查询其他区域的集群需要在data块上显式写region eu-west-1由 provider 的 region 逻辑注入到客户端若需要按标签、名称前缀等条件筛选只能在拿到names之后在 HCL 层用setintersect、setintersection等集合函数自行过滤数据源本身不提供服务端过滤。属性参考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 函数dataSourceClustersReadclusters_data_source.go的完整流程只有三步从 provider 元数据取得 EKS 客户端c.EKSClient(ctx)调用tfslices.CollectWithError(listClusters(ctx, conn, input))一次性收集所有分页的集群名称出错则通过sdkdiag.AppendFromErr转为 Terraform Diagnostics设置id与names。这里有两个值得注意的实现细节传入的input是一个空的eks.ListClustersInput——再次印证该 API 调用不带任何过滤条件返回的是区域内的全量集群名称数据源文件头部的SDKDataSource(aws_eks_clusters, nameClusters)注解用于代码生成见 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同时被两处复用本数据源aws_eks_clustersSDKv2 风格只导出名称集合框架层的list resourceaws_eks_clustercluster_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迭代器切片收集器CollectWithErrordocs/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),仅供参考