iac-terraform创建aws的基础实施VPC和eks

 

🧱 项目完整文件结构

text
terraform-eks-demo/
├── provider.tf          # 配置 Terraform 和 AWS Provider(包含密钥)
├── vpc.tf               # 手动创建 VPC、子网、路由表、网关等
├── eks.tf               # 创建 EKS 集群、节点组及相关 IAM 角色
├── outputs.tf           # 输出集群信息
└── variables.tf         # 变量定义(可选,这里为了演示区域等)


1、provider.tf – 配置 Terraform 和 AWS 凭证

# 指定 Terraform 的最低版本和所需的插件
terraform {
  required_version = ">= 1.0"          # Terraform 版本要求
  required_providers {
    aws = {
      source  = "hashicorp/aws"        # AWS Provider 的来源
      version = "~> 5.0"               # 使用 5.x 版本
    }
  }
}

# 配置 AWS Provider,直接写入 Access Key 和 Secret Key(仅为演示)
provider "aws" {
  region     = "us-west-2"             
  access_key = ""     # ⚠️ 你的 Access Key(请替换为真实值)
  secret_key = ""         # ⚠️ 你的 Secret Key(请替换为真实值)
  token      = ""
}

2、vpc.tf – 手动创建 VPC、子网、路由表、网关等

# 1. 创建 VPC
resource "aws_vpc" "main" {
  cidr_block           = "10.63.0.0/16"      # VPC 的 IP 地址范围(65536 个地址)
  enable_dns_support   = true               # 启用 DNS 解析(EKS 需要)
  enable_dns_hostnames = true               # 启用 DNS 主机名(EKS 需要)

  tags = {
    Name = "my-eks-vpc"
  }
}

# 2. 创建互联网网关(IGW),用于公共子网访问外网
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "my-eks-igw"
  }
}

# 3. 获取当前区域可用的可用区(用于分布子网)
data "aws_availability_zones" "available" {
  state = "available"                       # 只获取可用的可用区
}

# 4. 创建 3 个公共子网(分别位于前 3 个可用区)
resource "aws_subnet" "public" {
  count             = 3                     # 创建 3 个子网
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet("10.63.0.0/16", 8, count.index)        # 生成 10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24
  availability_zone = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true            # 自动分配公网 IP(对公共子网内的实例)

  tags = {
    Name = "public-subnet-${count.index}"
    # EKS 要求:公网子网打上特定标签,用于发现负载均衡器
    "kubernetes.io/role/elb" = "1"
  }
}

# 5. 创建 3 个私有子网
resource "aws_subnet" "private" {
  count             = 3
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet("10.63.0.0/16", 8, count.index + 10)   # 生成 10.0.10.0/24, 10.0.11.0/24, 10.0.12.0/24
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "private-subnet-${count.index}"
    # EKS 要求:私有子网打上内部负载均衡器的标签
    "kubernetes.io/role/internal-elb" = "1"
  }
}

# 6. 创建弹性 IP(用于 NAT 网关)
resource "aws_eip" "nat" {
  domain = "vpc"                           # 表示在 VPC 中使用

  tags = {
    Name = "my-eks-nat-eip"
  }
}

# 7. 创建 NAT 网关(放在一个公共子网中,为私有子网提供外网访问)
resource "aws_nat_gateway" "nat" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public[0].id   # 放在第一个公共子网

  tags = {
    Name = "my-eks-nat"
  }
}

# 8. 创建公共路由表(关联公共子网,路由指向 IGW)
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"               # 所有目的地址
    gateway_id = aws_internet_gateway.igw.id # 指向互联网网关
  }

  tags = {
    Name = "public-rt"
  }
}

# 9. 将公共路由表关联到每个公共子网
resource "aws_route_table_association" "public" {
  count          = 3
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

# 10. 创建私有路由表(关联私有子网,路由指向 NAT 网关)
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat.id   # 指向 NAT 网关
  }

  tags = {
    Name = "private-rt"
  }
}

# 11. 将私有路由表关联到每个私有子网
resource "aws_route_table_association" "private" {
  count          = 3
  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private.id
}

 

3、eks.tf – 创建 EKS 集群和节点组(含 IAM)

# 1. IAM 角色:供 EKS 集群控制平面使用
resource "aws_iam_role" "eks_cluster" {
  name = "my-eks-cluster-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "eks.amazonaws.com"   # 允许 EKS 服务扮演此角色
        }
      },
    ]
  })
}

# 2. 将 AmazonEKSClusterPolicy 托管策略附加到集群角色
resource "aws_iam_role_policy_attachment" "eks_cluster" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = aws_iam_role.eks_cluster.name
}

# 3. IAM 角色:供 EKS 工作节点(EC2)使用
resource "aws_iam_role" "eks_nodes" {
  name = "my-eks-node-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"   # 允许 EC2 服务扮演此角色
        }
      },
    ]
  })
}

# 4. 附加工作节点所需的核心策略
resource "aws_iam_role_policy_attachment" "eks_node_policy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
  role       = aws_iam_role.eks_nodes.name
}

resource "aws_iam_role_policy_attachment" "eks_cni_policy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
  role       = aws_iam_role.eks_nodes.name
}

resource "aws_iam_role_policy_attachment" "ec2_container_registry_read_only" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = aws_iam_role.eks_nodes.name
}

# 5. 创建 EKS 集群(控制平面)
resource "aws_eks_cluster" "main" {
  name     = "my-eks-cluster"
  role_arn = aws_iam_role.eks_cluster.arn
  version  = "1.35"                       # Kubernetes 版本

  vpc_config {
    subnet_ids = aws_subnet.private[*].id   # 将集群控制平面部署在私有子网中(官方推荐)
  }

  # 确保 IAM 策略已经附加
  depends_on = [
    aws_iam_role_policy_attachment.eks_cluster
  ]
}

# 6. 创建 EKS 托管节点组(工作节点)
resource "aws_eks_node_group" "main" {
  cluster_name    = aws_eks_cluster.main.name
  node_group_name = "my-node-group"
  node_role_arn   = aws_iam_role.eks_nodes.arn
  subnet_ids      = aws_subnet.private[*].id    # 工作节点也放在私有子网
  instance_types  = ["t3.medium"]               # 实例规格

  scaling_config {
    desired_size = 2
    max_size     = 3
    min_size     = 1
  }

  # 集群必须先就绪
  depends_on = [
    aws_eks_cluster.main,
  ]

  tags = {
    Name = "my-eks-worker"
  }
}

4、outputs.tf – 输出集群信息

output "cluster_name" {
  description = "EKS 集群名称"
  value       = aws_eks_cluster.main.name
}

output "cluster_endpoint" {
  description = "EKS API Server 地址"
  value       = aws_eks_cluster.main.endpoint
}

output "cluster_certificate_authority" {
  description = "集群 CA 证书(base64 编码)"
  value       = aws_eks_cluster.main.certificate_authority[0].data
}

 

🚀 部署步骤

  1. 替换密钥:将 provider.tf 中的 access_key 和 secret_key 换成你自己的真实密钥。

  2. 初始化:terraform init

  3. 预览:terraform plan(会列出约 30 多个资源)

  4. 应用:terraform apply -auto-approve(等待 10-15 分钟)

  5. 配置 kubeconfig:
    aws eks update-kubeconfig --region us-west-2 --name my-eks-cluster

  6. 测试:kubectl get nodes


🧹 清理资源

bash
terraform destroy -auto-approve

 

5、mac配置访问凭证和安装kubectl

配置访问凭证

export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
export AWS_SESSION_TOKEN=""
aws eks update-kubeconfig --region us-west-2 --name my-eks-cluster

安装kubectl

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

brew install kubectl

验证

kubectl get nodes

 

 

 

 

 

posted @ 2026-04-07 14:14  苦逼yw  阅读(1)  评论(0)    收藏  举报