You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过单次Terraform Apply完成EKS集群创建与Kubernetes部署?

实现单次Terraform Apply完成EKS创建、镜像构建与K8s部署

核心方案:动态配置Kubernetes Provider

Terraform支持通过资源输出值动态配置Provider参数,结合依赖关系确保K8s Provider在EKS集群创建完成后才初始化。以下是完整实现步骤:


1. 配置AWS Provider与EKS集群资源

先定义AWS Provider,创建EKS集群、节点组及存储镜像的ECR仓库:

provider "aws" {
  region = "us-east-1" # 替换为你的目标区域
}

# 创建ECR仓库存储自定义镜像
resource "aws_ecr_repository" "app_repo" {
  name = "my-custom-app"
  image_tag_mutability = "MUTABLE"
}

# EKS集群IAM角色
resource "aws_iam_role" "eks_cluster" {
  name = "eks-cluster-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "eks.amazonaws.com"
      }
    }]
  })
}

resource "aws_iam_role_policy_attachment" "eks_cluster_policy" {
  role       = aws_iam_role.eks_cluster.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}

# 创建EKS集群
resource "aws_eks_cluster" "main" {
  name     = "my-eks-cluster"
  role_arn = aws_iam_role.eks_cluster.arn

  vpc_config {
    subnet_ids = aws_subnet.private.*.id # 替换为你的私有子网ID列表
  }

  depends_on = [aws_iam_role_policy_attachment.eks_cluster_policy]
}

# EKS节点组IAM角色
resource "aws_iam_role" "eks_node" {
  name = "eks-node-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
    }]
  })
}

resource "aws_iam_role_policy_attachment" "eks_node_policy" {
  role       = aws_iam_role.eks_node.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
}

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

# 创建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_node.arn
  subnet_ids      = aws_subnet.private.*.id
  scaling_config {
    desired_size = 2
    min_size     = 1
    max_size     = 3
  }

  depends_on = [
    aws_iam_role_policy_attachment.eks_node_policy,
    aws_eks_cluster.main
  ]
}

2. 获取EKS集群认证令牌

通过aws_eks_cluster_auth数据源获取集群访问令牌,用于Kubernetes Provider认证:

data "aws_eks_cluster_auth" "main" {
  name = aws_eks_cluster.main.name

  depends_on = [aws_eks_cluster.main]
}

3. 动态配置Kubernetes Provider

直接引用EKS集群的输出值配置K8s Provider,Terraform会自动处理依赖,确保集群就绪后才初始化Provider:

provider "kubernetes" {
  host                   = aws_eks_cluster.main.endpoint
  cluster_ca_certificate = base64decode(aws_eks_cluster.main.certificate_authority.0.data)
  token                  = data.aws_eks_cluster_auth.main.token

  # 显式依赖节点组,确保节点加入集群后再部署资源
  depends_on = [aws_eks_node_group.main]
}

4. 构建并推送自定义Docker镜像

使用docker_image资源构建镜像,并通过本地命令登录ECR完成推送:

resource "docker_image" "custom_app" {
  name         = "${aws_ecr_repository.app_repo.repository_url}:latest"
  build {
    context = "./app" # 替换为你的Dockerfile所在目录路径
    dockerfile = "Dockerfile"
  }

  # 登录ECR并推送镜像
  provisioner "local-exec" {
    command = "aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${aws_ecr_repository.app_repo.repository_url}"
  }

  depends_on = [aws_ecr_repository.app_repo]
}

5. 部署Kubernetes应用

定义Deployment资源,Terraform会在镜像推送完成、集群就绪后自动部署Pod:

resource "kubernetes_deployment" "app_deployment" {
  metadata {
    name = "custom-app"
    labels = {
      app = "custom-app"
    }
  }

  spec {
    replicas = 2
    selector {
      match_labels = {
        app = "custom-app"
      }
    }

    template {
      metadata {
        labels = {
          app = "custom-app"
        }
      }

      spec {
        container {
          image = docker_image.custom_app.name
          name  = "custom-app"
          port {
            container_port = 80
          }
        }
      }
    }
  }

  depends_on = [docker_image.custom_app]
}

关键注意事项

  • 执行顺序:通过depends_on严格控制资源创建顺序:ECR仓库 → EKS集群/节点组 → K8s Provider → 镜像构建推送 → K8s部署。
  • 环境要求:执行terraform apply的机器需安装Docker和AWS CLI,且配置足够权限操作EKS、ECR资源。
  • 节点就绪:Kubernetes Provider依赖节点组,确保节点成功加入集群后再部署应用,避免Pod调度失败。

内容的提问来源于stack exchange,提问作者curiousgeek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:06:29