
Terraform AWS Provider 中 aws_eks_cluster_auth 数据源的原理与实战预签名 STS 请求生成 EKS 认证 Token【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws在 Terraform 中管理 EKS 集群时aws_eks_cluster_auth数据源负责利用当前 AWS 凭证生成一个与 AWS IAM Authenticator 兼容的临时认证 Token供kubernetes、helm等 Provider 直接接入集群。读完本文你将掌握该数据源的完整参数与属性、Token 背后的“预签名 STS GetCallerIdentity 请求”工作机制、15 分钟有效期的来源以及它在 Terraform AWS Provider 仓库中的源码实现与测试验证方式。数据源概述aws_eks_cluster_auth用于获取一个可以与 EKS 集群通信的认证 Token。它使用 AWS Provider 中配置的 IAM 凭证生成临时 Token该 Token 与 AWS IAM Authenticator 的认证机制兼容因此既可以用于认证到 EKS 集群也可以用于任何配置了 AWS IAM Authenticator 服务端的集群。NOTE原文档提示通过数据源动态配置 Terraform Provider 在 Terraform 1.3.0 以下版本会对资源导入支持产生影响对应上游 Terraform issue #13018。在使用该数据源驱动provider kubernetes配置时需要注意这一版本前提。示例用法文档给出的标准用法是将aws_eks_cluster、aws_eks_cluster_auth两个数据源组合驱动kubernetesProviderdata aws_eks_cluster example { name example } data aws_eks_cluster_auth example { name example } provider kubernetes { host data.aws_eks_cluster.example.endpoint cluster_ca_certificate base64decode(data.aws_eks_cluster.example.certificate_authority[0].data) token data.aws_eks_cluster_auth.example.token }要点说明data.aws_eks_cluster.example.endpoint提供 API Server 地址certificate_authority[0].data是 Base64 编码的 CA 证书需用base64decode()解码token来自aws_eks_cluster_auth作为 Bearer Token 注入kubernetesProvider 的请求头。仓库中还有一个与数据源配套的 ephemeral resource 用法ephemeral aws_eks_cluster_auth示例同时接入了kubernetes与helm两个 Provider可参考 ephemeral 资源文档。参数与属性参考参数Argument Reference参数必填说明name是集群名称。源码中使用validation.NoZeroValues校验即不允许空值region否该资源所在区域默认继承 Provider 配置中的 Region属性Attribute Reference属性说明id集群名称d.SetId(name)token用于向集群认证令牌的 Token。在 schema 中标记为Sensitive: trueTerraform 输出/日志中会遮蔽该值底层实现一次预签名的 STS GetCallerIdentity 调用数据源读取逻辑数据源实现位于 cluster_auth_data_source.go。其核心读取流程非常简短func dataSourceClusterAuthRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { var diags diag.Diagnostics conn : meta.(*conns.AWSClient).STSClient(ctx) name : d.Get(names.AttrName).(string) generator, err : NewGenerator(false, false) // ... token, err : generator.GetWithSTS(ctx, name, conn) // ... d.SetId(name) d.Set(token, token.Token) return diags }可以看到三步关键操作通过conns.AWSClient的STSClient(ctx)取得 STS 客户端——也就是复用 AWS Provider 已配置好的凭证链静态凭证、环境变量、实例角色等均可调用NewGenerator(false, false)创建 Token 生成器两个参数分别为forwardSessionName与cache数据源场景下均关闭缓存保证每次读取都签发新 Token调用generator.GetWithSTS(ctx, name, conn)生成 Token并把集群名设为资源 ID。Token 的实际形态真正的生成逻辑在 token.go。该文件头部注释明确说明它是 Kubernetes 官方 aws-iam-authenticator 项目pkg/token/token.go的硬拷贝hard copy并针对 AWS SDK for Go v2 做了适配仅保留了GetWithSTS一条生成路径。GetWithSTS的实现核心是presigner : sts.NewPresignClient(stsAPI, func(po *sts.PresignOptions) { po.ClientOptions []func(*sts.Options){ func(o *sts.Options) { o.APIOptions []func(*middleware.Stack) error{ addClusterIdHeaderSetterMiddleware(clusterID), addExpiryParamSetterMiddleware(requestPresignParam), } }, } }) request, err : presigner.PresignGetCallerIdentity(ctx, sts.GetCallerIdentityInput{}) // ... return Token{v1Prefix base64.RawURLEncoding.EncodeToString([]byte(request.URL))}, nil也就是说Token并不是一次真实的 API 调用返回的字符串而是一个被预签名presign的GetCallerIdentityHTTPS URL 经 Base64 URL 编码后的产物外加k8s-aws-v1.前缀。具体机制包括集群绑定中间件向请求头注入x-k8s-aws-id常量clusterIDHeader其值为集群名并把该头加入签名头signed headers。AWS IAM Authenticator 校验时要求该头必须被签名从而把 Token 与特定集群绑定有效期预签名的 STS URL 在X-Amz-Date时间戳起 15 分钟后过期常量presignedURLExpiration 15 * time.Minute。而X-Amz-Expires参数被固定设为 60注释中说明这是为了兼容 0.3.0 及更早版本 authenticator 的服务端检查要求该值在 0 到 60 之间实际过期由X-Amz-Date决定Token 上限校验端要求 Token 长度不超过 4KBmaxTokenLenBytes 1024 * 4。校验端Verifier同一文件中保留了校验逻辑Verify(token)它正是接受测试和 AWS 服务端使用的同款校验流程可作为 Token 格式规范的“活文档”长度不得超过 4KB否则报token is too large必须以k8s-aws-v1.前缀开头否则报缺少前缀Base64RawURLEncoding解码后解析 URL要求 scheme 为https主机名必须匹配^sts(\.[a-z1-9\-])?\.amazonaws\.com(\.cn)?$即只接受全球/区域 STS 端点含中国站点.amazonaws.com.cn路径必须为/查询参数必须全部落在白名单内Action、Version、x-amz-algorithm、x-amz-credential、x-amz-date、x-amz-expires、x-amz-security-token、x-amz-signature、x-amz-signedheadersAction必须为GetCallerIdentity且x-k8s-aws-id头必须出现在签名头中x-amz-expires必须在 0 到 900 秒之间x-amz-date必须存在且尚未超过 15 分钟过期窗口。校验通过后验证器会真正发起该 GET 请求携带集群名头解析GetCallerIdentity响应得到包含ARN、CanonicalARN将assumed-roleARN 归一化为 IAM 角色 ARN、AccountID、UserID、SessionName、AccessKeyID的Identity结构。测试验证验收测试生成后回验 Token数据源的验收测试位于 cluster_auth_data_source_test.go。测试配置只有三行data aws_eks_cluster_auth test { name foobar }检查逻辑testAccCheckClusterAuthToken并不只是断言token非空而是从状态中取出name与token调用tfeks.NewVerifier(name)执行verifier.Verify(tok)真实地向 STS 端点发起校验并确认返回的身份 ARN 非空。也就是说测试链路完整覆盖了“生成 → 校验 → 身份解析”的闭环。单元测试Token 格式的边界矩阵token_test.go 同样是 aws-iam-authenticator 测试的硬拷贝提供了非常细粒度的边界验证TestSTSEndpoints枚举全球、美国、亚太、欧洲、中东、中国等 18 个 STS 端点主机名验证verifyHost全部通过TestVerifyTokenPreSTSValidations构造超长 Token、错误前缀k8s-aws-v2.、非法 Base64、httpscheme、非 STS 主机如google.com、非/路径、非白名单参数、多值参数、错误 Action、未签名x-k8s-aws-id头、x-amz-expires超限、x-amz-date格式错误、时间戳过期等失败用例以及多个区域端点的成功用例TestVerifyNoSession/TestVerifySessionName/TestVerifyCanonicalARN验证身份解析——无会话用户的 ARN/UserID、含会话名UserID:SessionName的拆分以及arn:aws:sts::...assumed-role/Alice/extra归一化为arn:aws:iam::...role/Alice的行为HTTP 层错误路径403 响应、连接错误、响应体读取失败、JSON 解析失败等均以STSError类型返回。Ephemeral Resource 变体仓库中还存在一个功能等价的 ephemeral resource见 cluster_auth_ephemeral.go 与 其文档ephemeral aws_eks_cluster_auth example { name data.aws_eks_cluster.example.id }从源码结构看其Open方法与数据源读取逻辑完全一致NewGenerator(false, false)GetWithSTS STS 客户端属性同样是nameRequired与tokenComputed、Sensitive并支持region参数。使用 ephemeral 形态可以让 Token 在应用后即从内存中清除避免像数据源那样停留在状态文件中适合把 Token 传给kubernetes/helm等 Provider 的敏感场景。需注意官方文档同时提示ephemeral resource 是 Terraform 的新特性仍在演进中。实践要点小结15 分钟有效期Token 基于预签名 URL 的X-Amz-Date计算15 分钟后失效。若长时任务如 CI 流水线中途 Token 过期需要重新运行 plan/apply 或改用 IAM 角色等自动刷新凭证的方式凭证来源透明数据源不接收任何显式凭证参数完全依赖 AWS Provider 配置的凭证链region亦默认继承 Provider 区域Token 可移植性强由于 Token 本质是带签名的 URL 编码串任何实现了 AWS IAM Authenticator 服务端校验的集群不仅是 AWS 托管 EKS都可接受该 Token敏感性token属性在数据源 schema 中标记为 Sensitive且数据源文档明确提醒 Terraform 1.3.0 下由数据源动态配置 Provider 会限制相关资源的导入支持。相关源码路径索引内容路径数据源文档website/docs/d/eks_cluster_auth.html.markdownEphemeral 资源文档website/docs/ephemeral-resources/eks_cluster_auth.html.markdown数据源实现internal/service/eks/cluster_auth_data_source.goEphemeral 资源实现internal/service/eks/cluster_auth_ephemeral.goToken 生成与校验internal/service/eks/token.go数据源验收测试internal/service/eks/cluster_auth_data_source_test.goToken 单元测试internal/service/eks/token_test.go【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考