EKS Auto Modeが有効なAmazon EKSクラスターにGitLabをHelmを使ってデプロイしてみる
以前、EKS Auto Modeを無効にしたEKSクラスターにGitLabをインストールしました。
今回はEKS Auto Modeを有効にして、GitLabをインストールしてみようと思います。
EKS Auto Modeとは
概要は以下のブログをご確認ください。
ざっくりいうと、ワーカーノードのEC2やアドオンをAWS側で管理してくれる機能です。
冒頭のブログではEKS Auto Mode無効状態で、EKSにGitLabをインストールする方法を紹介しています。
EKS Auto Modeが有効な環境であれば、冒頭のブログ内の以下の作業が不要です。
- マネージドノードグループの設定
- EBS CSIアドオンのインストール
- AWS Load Balancer Controllerのインストール
- 上記アドオン・Controller用のService Account・IAM Role作成・関連付け(IRSA or Pod Identity)
運用フェーズの以下の作業も不要になり、運用の負荷も軽減されます。
- アドオンの更新
- ワーカーノードEC2のパッチ適用
EKS Auto Modeのデメリットは以下です。
- Fargateが使えない
- ノードへの直接アクセスができない
- EC2インスタンスの管理料金が発生する
Fargateに関しては、現時点(2025/3時点)ではGitLab HelmチャートがFargateに対応していないため、気にしなくて良さそうです。(GitLab Runner Helmチャートは対応している)
Use EC2 managed nodes for the EKS cluster, and not Fargate.Fargate has a number of limitations and is not supported for use with the GitLab Helm chart.
Preparing EKS resources for the GitLab chart | GitLab Docs
EKS Auto Mode自体にも料金がかかることにも注意してください。
起動したEC2インスタンスタイプに基づいて異なる管理料金が発生します。
EKS Clusterの構築
Terraformを使って構築します。
NetworkとClusterでStatefileを分けて構築しました。
HCP Terraform上でStatefileを管理しており、Statefileの値の受け渡しはHCP Terraformに依存する部分があります。
BackendにS3を使っている場合は、適宜読み替えていただければと思います。(リソースを少し置き換えるくらいなので、流用は可能だと思います)
ディレクトリ構成は以下です。
.
├── netowrk/
│   ├── main.tf
│   ├── outputs.tf
│   ├── providers.tf
│   ├── variables.tf
│   └── terraform.tfvars
├── cluster/
│   ├── main.tf
│   ├── outputs.tf
│   ├── providers.tf
│   ├── variables.tf
│   └── terraform.tfvars
└── kube/
    ├── main.tf
    ├── outputs.tf
    ├── providers.tf
    ├── variables.tf
    └── terraform.tfvars
以降で紹介するファイルが用意できたら、以下のコマンドでそれぞれデプロイします。
terraform -chdir=network init
terraform -chdir=network plan
terraform -chdir=network apply
# networkの部分をclusterやkubeに置き換えてデプロイする
依存関係があるため、network -> cluster -> kube の順番に実行してください。
Network
terraform {
  cloud {
    organization = "<HCP Terraform Organizations名>"
    workspaces {
      name    = "gitlab-eks-network"
      project = "<HCP Terraform Project名>"
    }
  }
  required_version = "~> 1.11.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.93.0"
    }
  }
}
provider "aws" {
  region = var.region
}
variable "vpc_cidr" {
  type        = string
  description = "The CIDR block for the VPC"
  default     = "10.0.0.0/16"
}
variable "secondary_cidr_blocks" {
  type        = list(string)
  description = "The secondary CIDR blocks for the VPC"
  default     = ["10.1.0.0/16", "10.2.0.0/16"]
}
variable "prefix" {
  type        = string
  description = "The prefix to use for all resources"
  default     = "gitlab"
}
variable "region" {
  type        = string
  description = "The AWS region to deploy to"
  default     = "us-east-2"
}
EKS Clusterがサブネット種別を判別できるようにkubernetes.io/role/elb kubernetes.io/role/internal-elbのタグをそれぞれ付与します。
data "aws_availability_zones" "available" {}
locals {
  azs = slice(data.aws_availability_zones.available.names, 0, 3)
  tags = {
    project    = var.prefix
    managed_by = "Terraform"
  }
}
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.19.0"
  name                  = var.prefix
  cidr                  = var.vpc_cidr
  secondary_cidr_blocks = var.secondary_cidr_blocks
  azs = local.azs
  private_subnets = [for k, v in local.azs : cidrsubnet(var.vpc_cidr, 2, k)]
  public_subnets  = [for k, v in local.azs : cidrsubnet(var.secondary_cidr_blocks.0, 2, k)]
  intra_subnets   = [for k, v in local.azs : cidrsubnet(var.secondary_cidr_blocks.1, 2, k)]
  map_public_ip_on_launch = true
  enable_nat_gateway      = true
  single_nat_gateway      = true
  create_egress_only_igw  = true
  public_subnet_tags = {
    "subnet-type" = "public"
    "kubernetes.io/role/elb" = 1
  }
  private_subnet_tags = {
    "subnet-type" = "private"
    "kubernetes.io/role/internal-elb" = 1
  }
  tags = local.tags
}
output "vpc" {
  value = module.vpc
}
hcp_tf_organization="<HCP Terraform Organization名>"
Cluster
terraform {
  cloud {
    organization = "<HCP Terraform Organizations名>"
    workspaces {
      name    = "gitlab-eks-cluster-automode"
      project = "<HCP Terraform Project名>"
    }
  }
  required_version = "~> 1.11.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.93.0"
    }
    tfe = {
      source  = "hashicorp/tfe"
      version = "~> 0.63.0"
    }
  }
}
provider "aws" {
  region = var.region
}
variable "eks_version" {
  type        = string
  description = "The EKS version to use"
  default     = "1.30"
}
variable "prefix" {
  type        = string
  description = "The prefix to use for all resources"
  default     = "gitlab"
}
variable "region" {
  type        = string
  description = "The AWS region to deploy to"
  default     = "us-east-2"
}
variable "hcp_tf_organization" {
  type        = string
  description = "The name of the HCP Terraform organization"
}
variable "hcp_tf_network_workspace" {
  type        = string
  description = "The name of the HCP Terraform workspace for the network"
  default     = "gitlab-eks-network"
}
variable "eks_admin_iam_role_arn" {
  type        = string
  description = "The ARN of the IAM role to use for the EKS admin"
}
EKS Auto Modeの有効化設定はシンプルで、cluster_compute_configの部分が該当します。
マネージドノードグループの場合は、インスタンスタイプ等を設定する必要がありますが、EKS Auto Modeでは不要です。
E
KS Auto Modeが無効な環境では、EBS CIS Driver等のアドオンを定義する必要がありました。
Auto Modeでは、EBS CIS DriverやCoreDNS等が組み込まれているためTerraform上でも定義する必要がありません。
data "aws_availability_zones" "available" {}
locals {
  azs = slice(data.aws_availability_zones.available.names, 0, 3)
  tags = {
    project    = var.prefix
    managed_by = "Terraform"
  }
}
data "tfe_outputs" "network" {
  organization = var.hcp_tf_organization
  workspace    = var.hcp_tf_network_workspace
}
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.34.0"
  cluster_name    = var.prefix
  cluster_version = var.eks_version
  cluster_endpoint_public_access = true
  cluster_ip_family              = "ipv4"
  vpc_id                         = data.tfe_outputs.network.values.vpc.vpc_id
  subnet_ids                     = concat(data.tfe_outputs.network.values.vpc.private_subnets, data.tfe_outputs.network.values.vpc.public_subnets)
  create_kms_key            = false
  cluster_encryption_config = {}
  enable_cluster_creator_admin_permissions = true
  enable_irsa                              = false
  cluster_compute_config = {
    enabled    = true
    node_pools = ["general-purpose", "system"]
  }
  access_entries = {
    default = {
      kubernetes_groups = []
      principal_arn     = var.eks_admin_iam_role_arn
      policy_associations = {
        default = {
          policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
          access_scope = {
            type = "cluster"
          }
        }
      }
    },
  }
}
output "eks" {
  value = module.eks
}
hcp_tf_organization="<HCP Terraform Organization名>"
Kubernetes
terraform {
  cloud {
    organization = "<HCP Terraform Organizations名>"
    workspaces {
      name    = "gitlab-eks-kube-automode"
      project = "<HCP Terraform Project名>"
    }
  }
  required_version = "~> 1.11.0"
  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.36.0"
    }
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.93.0"
    }
    tfe = {
      source  = "hashicorp/tfe"
      version = "~> 0.63.0"
    }
  }
}
provider "aws" {
  region = var.region
}
data "tfe_outputs" "cluster" {
  organization = var.hcp_tf_organization
  workspace    = var.hcp_tf_cluster_workspace
}
data "aws_eks_cluster_auth" "this" {
  name = data.tfe_outputs.cluster.values.eks.cluster_name
}
provider "kubernetes" {
  host                   = data.tfe_outputs.cluster.values.eks.cluster_endpoint
  cluster_ca_certificate = base64decode(data.tfe_outputs.cluster.values.eks.cluster_certificate_authority_data)
  token                  = data.aws_eks_cluster_auth.this.token
}
variable "region" {
  type        = string
  description = "The AWS region to deploy to"
  default     = "us-east-2"
}
variable "hcp_tf_organization" {
  type        = string
  description = "The name of the HCP Terraform organization"
}
variable "hcp_tf_cluster_workspace" {
  type        = string
  description = "The name of the HCP Terraform workspace for the cluster"
  default     = "gitlab-eks-cluster-automode"
}
EKS AutoModeでEBSボリュームを使うには、StorageClassを定義する必要があります。(kubernetes_storage_class.auto_ebs_sc)
ALBを作成するには、IngressClassが必要です。(kubernetes_manifest.alb_ingress_class_params kubernetes_ingress_class_v1.alb)
今回はそれぞれ公式ドキュメントにて紹介されている設定で設定しました。
IngressClass を作成して Application Load Balancer を設定する - Amazon EKS
# Namespace
resource "kubernetes_namespace" "gitlab" {
  metadata {
    name = "gitlab"
    labels = {
      name = "gitlab"
    }
  }
}
# StorageClass
resource "kubernetes_storage_class" "auto_ebs_sc" {
  metadata {
    name = "auto-ebs-sc"
    annotations = {
      "storageclass.kubernetes.io/is-default-class" = "true"
    }
  }
  storage_provisioner    = "ebs.csi.eks.amazonaws.com"
  volume_binding_mode    = "WaitForFirstConsumer"
  parameters = {
    type      = "gp3"
    encrypted = "true"
  }
}
# Ingress
resource "kubernetes_manifest" "alb_ingress_class_params" {
  manifest = {
    apiVersion = "eks.amazonaws.com/v1"
    kind       = "IngressClassParams"
    metadata = {
      name = "alb"
    }
    spec = {
      scheme = "internet-facing"
    }
  }
}
resource "kubernetes_ingress_class_v1" "alb" {
  metadata {
    name = "alb"
    annotations = {
      "ingressclass.kubernetes.io/is-default-class" = "true"
    }
  }
  spec {
    controller = "eks.amazonaws.com/alb"
    parameters {
      api_group = "eks.amazonaws.com"
      kind      = "IngressClassParams"
      name      = "alb"
    }
  }
}
hcp_tf_organization="<HCP Terraform Organization名>"
GitLabのインストール・Route53レコードにALBを登録・アクセスの確認
以下の記事の手順で実施します。
後片付け
helmでデプロイしたリソースの削除
helm uninstall gitlab
kubectl delete pvc,pv -l release=gitlab
Terraformデプロイしたリソースの削除
terraform -chdir=kube destroy
terraform -chdir=cluster plan
terraform -chdir=network apply
ACM・Route53レコード削除
必要に応じて、ACMで作成した証明書やGitLab用のRoute53 レコードを削除してください。
おわりに
Auto Mode無効のGitLab Clusterへのインストールと比べると手順が楽ですね。
マネージドノードグループと比較して、Terraformの記述自体もシンプルでした。
Helmチャート関連は変更なくデプロイできました。
変更が必要そうな箇所としては、ノードの管理方法が異なるためGitLab Runnerとノードを分離したい場合の設定部分です。
こちらについても、後ほどブログにしようと思います。
以上、AWS事業本部の佐藤(@chari7311)でした。)
参考












