news 2026/9/17 0:09:38

terraform-provider-aws EKS 入门指南:用 Terraform 一键搭建 Amazon EKS 集群的完整配置解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
terraform-provider-aws EKS 入门指南:用 Terraform 一键搭建 Amazon EKS 集群的完整配置解析

terraform-provider-aws EKS 入门指南:用 Terraform 一键搭建 Amazon EKS 集群的完整配置解析

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

本指南以terraform-provider-aws仓库中的 examples/eks-getting-started 示例为骨架,完整讲解如何使用 Terraform 与 AWS Provider 从零搭建一套可运行的 Amazon EKS 集群——包括 VPC 网络、EKS 控制平面、IAM 角色与节点组(Node Group)。读完本文,你将掌握该示例中每个配置文件的职责、核心资源参数的含义与默认值,以及如何一键应用、生成 kubeconfig 并接入 Kubernetes。

该示例源自 HashiCorp 官方 EKS 入门指南(Getting Started Guide),仓库中保留了全部可运行的配置:providers.tfvariables.tfvpc.tfeks-cluster.tfeks-worker-nodes.tfoutputs.tfworkstation-external-ip.tf七个文件共同组成一个完整的端到端方案,本文将逐一剖析。

示例整体架构:七个文件各司其职

在动手之前,先建立对整体结构的认知。该示例的核心思想是:用最少的资源组合出一条可用的 EKS 集群最小链路——VPC 提供网络底座,IAM 角色授权 EKS 服务与节点运行,安全组放行工作站的 API 访问,最终由aws_eks_clusteraws_eks_node_group完成集群与工作节点的创建。各文件职责如下:

文件职责
providers.tf声明 Terraform 版本约束、AWS Provider 与 HTTP Provider,并读取可用可用区
variables.tf定义aws_regioncluster_name两个输入变量
vpc.tf创建 VPC、两个子网、互联网网关、路由表与关联
eks-cluster.tf创建集群 IAM 角色、安全组与aws_eks_cluster控制平面
eks-worker-nodes.tf创建节点 IAM 角色与aws_eks_node_group工作节点
outputs.tf生成aws-authConfigMap 与 kubeconfig 两个输出
workstation-external-ip.tf通过 HTTP Provider 获取工作站公网 IP,用于安全组放行

前置准备:Provider 与输入变量

providers.tf 是 Terraform 的入口配置,内容如下:

terraform { required_version = ">= 0.12" } provider "aws" { region = var.aws_region } data "aws_availability_zones" "available" {} # Not required: currently used in conjunction with using # icanhazip.com to determine local workstation external IP # to open EC2 Security Group access to the Kubernetes cluster. # See workstation-external-ip.tf for additional information. provider "http" {}

几个关键点:

  • required_version = ">= 0.12"声明了 Terraform 的最低版本要求,0.12 是 Terraform 引入 HCL2 语法与新表达式系统的里程碑版本,本示例使用的[*]展开、tomap等语法均依赖于此;
  • provider "aws"通过var.aws_region指定目标区域(默认us-west-2);
  • data "aws_availability_zones" "available" {}动态拉取当前区域可用的可用区列表,供后续子网分布使用——这正是 AWS Provider 数据源(Data Source)的典型用法;
  • provider "http" {}并非 EKS 必需,仅为配合workstation-external-ip.tf获取工作站公网 IP,属于安全组放行的辅助手段。

对应的 variables.tf 只暴露两个可调参数,保持了示例的最小化:

variable "aws_region" { default = "us-west-2" } variable "cluster_name" { default = "terraform-eks-demo" type = string }

cluster_name默认值为terraform-eks-demo,在整个示例中被反复引用——包括 VPC/子网的 Kubernetes 标签、安全组名称与 kubeconfig 生成。EKS 对集群名称有严格的约束(小写字母、数字、短横线,长度限制等),在 internal/service/eks/validate.go 中有对应的校验实现,改名时需符合命名规范。

网络底座:VPC、子网与路由

vpc.tf 构建了 EKS 运行所需的全部网络资源,这是集群能否对外提供服务的基础:

resource "aws_vpc" "demo" { cidr_block = "10.0.0.0/16" tags = tomap({ "Name" = "terraform-eks-demo-node", "kubernetes.io/cluster/${var.cluster_name}" = "shared", }) } resource "aws_subnet" "demo" { count = 2 availability_zone = data.aws_availability_zones.available.names[count.index] cidr_block = "10.0.${count.index}.0/24" map_public_ip_on_launch = true vpc_id = aws_vpc.demo.id tags = tomap({ "Name" = "terraform-eks-demo-node", "kubernetes.io/cluster/${var.cluster_name}" = "shared", }) } resource "aws_internet_gateway" "demo" { vpc_id = aws_vpc.demo.id tags = { Name = "terraform-eks-demo" } } resource "aws_route_table" "demo" { vpc_id = aws_vpc.demo.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.demo.id } } resource "aws_route_table_association" "demo" { count = 2 subnet_id = aws_subnet.demo[count.index].id route_table_id = aws_route_table.demo.id }

设计要点:

  • VPC 采用10.0.0.0/16,两个子网分别位于10.0.0.0/2410.0.1.0/24,通过count = 2data.aws_availability_zones.available.names[count.index]自动分布到两个不同的可用区。EKS 要求控制平面至少跨两个可用区部署子网,这是集群高可用的基础;
  • map_public_ip_on_launch = true让子网内实例自动获得公网 IP,配合互联网网关与默认路由,节点可以拉取镜像、上报状态;
  • kubernetes.io/cluster/${var.cluster_name} = "shared"标签是 EKS 发现子网的关键:AWS 通过该标签识别哪些子网属于此集群;shared表示子网可被多个集群共享;
  • 路由表将0.0.0.0/0指向互联网网关,实现子网的出网能力,这是节点能注册进集群、执行kubelet任务的前提。

控制平面:IAM 角色、安全组与 aws_eks_cluster

eks-cluster.tf 负责 EKS 集群控制平面的创建,包含三类资源。

集群 IAM 角色

EKS 控制平面需要代表你调用其他 AWS 服务(如 ELB、IAM、EC2),因此必须先建立信任关系与授权策略:

resource "aws_iam_role" "demo-cluster" { name = "terraform-eks-demo-cluster" assume_role_policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } POLICY } resource "aws_iam_role_policy_attachment" "demo-cluster-AmazonEKSClusterPolicy" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" role = aws_iam_role.demo-cluster.name } resource "aws_iam_role_policy_attachment" "demo-cluster-AmazonEKSVPCResourceController" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" role = aws_iam_role.demo-cluster.name }

assume_role_policy中的Principal.Service: eks.amazonaws.com允许 EKS 服务代入该角色;随后挂载两个 AWS 托管策略:

  • AmazonEKSClusterPolicy:授予 EKS 管理集群所需的基础权限(创建/管理 ENI、安全组、负载均衡器等);
  • AmazonEKSVPCResourceController:授予 EKS 管理 VPC 资源的权限,用于支持 Security Group for Pods 等高级网络特性。

集群安全组与工作站放行规则

resource "aws_security_group" "demo-cluster" { name = "terraform-eks-demo-cluster" description = "Cluster communication with worker nodes" vpc_id = aws_vpc.demo.id egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "terraform-eks-demo" } } resource "aws_security_group_rule" "demo-cluster-ingress-workstation-https" { cidr_blocks = [local.workstation-external-cidr] description = "Allow workstation to communicate with the cluster API Server" from_port = 443 protocol = "tcp" security_group_id = aws_security_group.demo-cluster.id to_port = 443 type = "ingress" }

安全组默认放行全部出站流量(-1协议、0.0.0.0/0);入站只开放一条规则——允许local.workstation-external-cidr(即你本机公网 IP)通过TCP 443访问集群 API Server。这正是workstation-external-ip.tf存在的意义:将kubectl所在工作站的 IP 动态写入规则,避免手动查询和写死 IP。

EKS 集群资源本体

resource "aws_eks_cluster" "demo" { name = var.cluster_name role_arn = aws_iam_role.demo-cluster.arn vpc_config { security_group_ids = [aws_security_group.demo-cluster.id] subnet_ids = aws_subnet.demo[*].id } depends_on = [ aws_iam_role_policy_attachment.demo-cluster-AmazonEKSClusterPolicy, aws_iam_role_policy_attachment.demo-cluster-AmazonEKSVPCResourceController, ] }

核心参数:

  • name:集群名称,直接取自var.cluster_name
  • role_arn:指向上述集群 IAM 角色;
  • vpc_config:指定集群控制平面运行的子网(aws_subnet.demo[*].id展开两个子网)与附加安全组;
  • depends_on显式声明依赖策略挂载完成后再创建集群——如果策略未就绪就调用CreateCluster,会因权限不足而失败。

从源码实现看,aws_eks_cluster在 internal/service/eks/cluster.go 中实现。其中删除逻辑(cluster.go)值得注意:当集群正在扩容时删除请求会失败,因此 Provider 用tfresource.Retry60 分钟超时内、以 30 秒轮询间隔对ResourceInUseException("in progress")进行重试,直到集群真正进入可删除状态。这解释了为什么实际使用中删除 EKS 集群往往需要等待较长时间——不是卡住,而是底层 API 的分布式一致性约束所致。

工作节点:Node Group 的创建

eks-worker-nodes.tf 创建承载业务 Pod 的节点组。

节点 IAM 角色

resource "aws_iam_role" "demo-node" { name = "terraform-eks-demo-node" assume_role_policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } POLICY } resource "aws_iam_role_policy_attachment" "demo-node-AmazonEKSWorkerNodePolicy" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" role = aws_iam_role.demo-node.name } resource "aws_iam_role_policy_attachment" "demo-node-AmazonEKS_CNI_Policy" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" role = aws_iam_role.demo-node.name } resource "aws_iam_role_policy_attachment" "demo-node-AmazonEC2ContainerRegistryReadOnly" { policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" role = aws_iam_role.demo-node.name }

与集群角色不同,节点角色信任的是EC2 服务ec2.amazonaws.com),并挂载三个托管策略:

  • AmazonEKSWorkerNodePolicy:允许节点与 EKS 控制平面通信(注册、上报状态);
  • AmazonEKS_CNI_Policy:允许 VPC CNI 插件为 Pod 分配弹性网卡与 IP;
  • AmazonEC2ContainerRegistryReadOnly:允许节点从 ECR 拉取容器镜像。

Node Group 资源

resource "aws_eks_node_group" "demo" { cluster_name = aws_eks_cluster.demo.name node_group_name = "demo" node_role_arn = aws_iam_role.demo-node.arn subnet_ids = aws_subnet.demo[*].id scaling_config { desired_size = 1 max_size = 1 min_size = 1 } depends_on = [ aws_iam_role_policy_attachment.demo-node-AmazonEKSWorkerNodePolicy, aws_iam_role_policy_attachment.demo-node-AmazonEKS_CNI_Policy, aws_iam_role_policy_attachment.demo-node-AmazonEC2ContainerRegistryReadOnly, ] }

关键点:

  • scaling_configdesired_sizemax_sizemin_size都设为1,即最小可运行的单节点集群,便于快速验证且节省成本;
  • 节点组同样通过depends_on等待三个策略挂载完成;
  • 未显式指定的ami_typecapacity_type在 internal/service/eks/node_group.go 中都有对应字段处理——ami_type默认使用与 Kubernetes 版本匹配的 EKS 优化 AMI,capacity_type默认ON_DEMAND按需实例,二者均可在实际项目中显式配置;
  • 从 node_group.go 可以看到,节点组的创建、删除与更新操作分别由waitNodegroupCreatedwaitNodegroupDeletedwaitNodegroupUpdateSuccessful三个等待函数轮询集群状态直至完成,这也是节点组apply需要数分钟的原因。

收尾输出:kubeconfig 与 aws-auth ConfigMap

outputs.tf 是示例的"交付层",通过两个locals模板动态拼接出接入集群所需的全部信息:

locals { config_map_aws_auth = <<CONFIGMAPAWSAUTH apiVersion: v1 kind: ConfigMap metadata: name: aws-auth namespace: kube-system data: mapRoles: | - rolearn: ${aws_iam_role.demo-node.arn} username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes CONFIGMAPAWSAUTH kubeconfig = <<KUBECONFIG apiVersion: v1 clusters: - cluster: server: ${aws_eks_cluster.demo.endpoint} certificate-authority-data: ${aws_eks_cluster.demo.certificate_authority[0].data} name: kubernetes contexts: - context: cluster: kubernetes user: aws name: aws current-context: aws kind: Config preferences: {} users: - name: aws user: exec: apiVersion: client.authentication.k8s.io/v1beta1 command: aws-iam-authenticator args: - "token" - "-i" - "${var.cluster_name}" KUBECONFIG } output "config_map_aws_auth" { value = local.config_map_aws_auth } output "kubeconfig" { value = local.kubeconfig }

两个输出的用途:

  • kubeconfig:使用aws_eks_cluster.demo.endpoint(API Server 地址)与certificate_authority[0].data(CA 证书)动态生成,认证方式采用aws-iam-authenticatortoken子命令,按集群名-i ${var.cluster_name}换取短期令牌。将该输出写入本地~/.kube/config即可用kubectl get nodes查看集群;
  • config_map_aws_auth:这是节点接入集群控制平面的"准入名单"。由于本示例创建的是托管节点组(Managed Node Group),在较新的 EKS 版本中节点会自动注册;该 ConfigMap 输出保留了两方面的价值:一是作为理解 RBAC 映射机制的教学素材(system:bootstrapperssystem:nodes两个组是 kubelet 注册的必备授权组),二是供使用自管节点或历史版本时手动kubectl apply使用。

工作站公网 IP 的自动获取

workstation-external-ip.tf 是一个可选但很实用的辅助模块:

data "http" "workstation-external-ip" { url = "http://ipv4.icanhazip.com" } # Override with variable or hardcoded value if necessary locals { workstation-external-cidr = "${chomp(data.http.workstation-external-ip.response_body)}/32" }

其原理是借助 providers.tf 中声明的 HTTP Provider,向ipv4.icanhazip.com发起一次 GET 请求,把返回的公网 IP 字符串经chomp去掉尾随换行后拼接为/32的 CIDR 段,供集群安全组的入站规则使用。

这也解释了 README 中的提示:该配置不是 EKS 必需的,完全可以替换。例如在团队协作或 CI 场景下,可将其改为变量输入或硬编码固定的办公网出口 IP,避免每次执行terraform apply时对公网服务的依赖。注意此时需同步调整 providers.tf 中provider "http" {}的声明。

一键部署:从 apply 到 kubectl 可用

将上述七个文件置于同一目录后,完整的操作流程如下:

# 1. 初始化工作目录,下载 AWS Provider 与 HTTP Provider terraform init # 2. 查看将要创建的资源清单(建议每次都执行,确认变更范围) terraform plan # 3. 应用配置,创建 VPC、IAM、EKS 集群与节点组 # 集群创建通常需要 10~20 分钟 terraform apply

等待apply完成后,利用输出接入集群:

# 查看两个输出值 terraform output kubeconfig terraform output config_map_aws_auth # 将 kubeconfig 写入本地并接入集群 terraform output -raw kubeconfig > ~/.kube/config # 验证节点状态(等待 Node 进入 Ready 状态) kubectl get nodes

随后即可按需kubectl apply -f部署业务应用。若要回收整套环境,直接执行terraform destroy即可——需要注意的是,如前述源码分析所示,集群删除过程可能因底层资源清理而持续较长时间(Provider 内置 60 分钟重试窗口,cluster.go),属正常现象。

延伸阅读

该示例是理解 EKS 资源的最小闭环,进一步深入可关注仓库中的以下材料:

  • 集群资源完整实现:internal/service/eks/cluster.go
  • 节点组资源完整实现:internal/service/eks/node_group.go
  • EKS 服务包入口与资源清单:internal/service/eks/README.md
  • 仓库根目录的使用说明与贡献指南:README.md

若需要 Fargate 无服务器运行方式,仓库还提供了aws_eks_fargate_profile的实现(internal/service/eks/fargate_profile.go),可在本示例基础上扩展对比。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 0:09:04

i5-7200U黑苹果实战:Kaby Lake核显在macOS Mojave上的完整驱动方案

1. 项目概述&#xff1a;一台被低估的办公本&#xff0c;如何蜕变成稳定可用的 macOS 工作站暗影精灵3&#xff08;HP Pavilion Gaming Laptop 15-BC500TX&#xff09;——这台2017年发布的入门级游戏本&#xff0c;搭载的是Intel 第七代 Kaby Lake 平台&#xff0c;典型配置为…

作者头像 李华
网站建设 2026/9/17 0:08:11

电动汽车充电智能调度:多目标优化与Matlab实现

1. 项目背景与核心价值去年参与某园区微电网项目时&#xff0c;我第一次深刻意识到电动汽车充电调度对电网负荷的冲击。晚上7点园区充电桩集中启动时&#xff0c;变压器负载率直接从40%飙升至85%&#xff0c;差点触发过载保护。这个经历让我开始关注如何通过智能调度实现"…

作者头像 李华
网站建设 2026/9/17 0:06:39

SSM框架实现环保公益网:架构、数据库与论文写作全攻略

简介&#xff1a;一套完整的SSM大连环保公益网毕业设计项目包&#xff0c;面向计算机相关专业学生&#xff0c;适合用于毕业设计、课程设计或期末大作业。项目基于SSM框架构建&#xff0c;涵盖新闻发布、活动展示、用户互动、数据统计等典型功能模块&#xff0c;前后端分离设计…

作者头像 李华
网站建设 2026/9/17 0:06:19

ThinkPHP6多微信管理系统源码架构与部署实战

简介&#xff1a;一套基于ThinkPHP 6、X-admin 2.2、layui 2.5.x构建的多微信管理系统后台源码&#xff0c;面向需要同时管理多个公众号并将微信支付对应到企业商户的开发团队。核心亮点是不依赖微信开放平台即可完成多账号接入&#xff0c;内置权限认证、附件管理、一键CURD等…

作者头像 李华
网站建设 2026/9/17 0:03:36

即梦AI保姆级教程:从生图到数字人,一站式搞定AI视频创作

即梦AI这个工具&#xff0c;最近被问到的频率实在太高了。很多人私信问我&#xff1a;现在AI生成视频、AI绘画到底选哪个平台&#xff0c;免费的、效果好的、容易上手的都有哪些&#xff1f;除了大家常挂在嘴边的可灵、海螺、Runway&#xff0c;还有一堆四个英文字母的工具&…

作者头像 李华