🐙

EKS とその上で動くリソースを terraform apply 一発でデプロイしてみた

に公開

Amazon EKS は、AWS で Kubernetes をホストしサービスを展開することができる方法の 1 つです。
そのデプロイには AWS マネージドコンソールや AWS CLI、eksctl、kubectl を駆使する必要があり、なかなか骨が折れますし、再現性についても難しいところがあります。

そこで、Terraform を使ったら terraform apply コマンド一発でどこまで再現性のあるデプロイができるのか、気になりました。
結論から言いますと... EKS のデプロイから任意の Helm Chart のインストール(今回は ArgoCD)まで、Terraform で、しかも null resource 無しにできました

本記事ではどのように実現したのか、具体的な Terraform コードを交えてご紹介します。


早速試してみる

サンプルコードは GitHub に公開しています。

https://github.com/defaultcf/get-started-eks-in-2025

今必要なものは課金可能な AWS アカウントと mise だけです。

mise install
terraform init
terraform apply

どう実現しているの?

何も特別なことはしておらず、null resource すら使っていません。
秘訣は、Terraform の Kubernetes プロバイダーと Helm プロバイダーを使うだけです。

https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs

https://registry.terraform.io/providers/hashicorp/helm/latest/docs

なんだそんなことか、と思われるでしょう。
ただ、terraform apply 一発で完結させるために、AWS プロバイダーで作成したリソースから得られるクレデンシャルを上手く渡してあげる必要があります。

次のようにプロバイダーを宣言しています。

provider "kubernetes" {
  host                   = aws_eks_cluster.main.endpoint
  cluster_ca_certificate = base64decode(aws_eks_cluster.main.certificate_authority.0.data)
  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    command     = "aws"
    args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.main.name]
  }
}

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

    exec {
      api_version = "client.authentication.k8s.io/v1beta1"
      command     = "aws"
      args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.main.name]
    }
  }
}

正直これだけです。あとは堅実にリソースを宣言していきます。

Helm Chart のインストールはこんな感じ。

resource "helm_release" "argocd" {
  name       = "argocd"
  repository = "https://argoproj.github.io/argo-helm"
  chart      = "argo-cd"
  version    = "7.8.3"
  namespace  = kubernetes_namespace.argocd.metadata.0.name
}

resource "helm_release" "load_balancer_controller" {
  name       = "aws-load-balancer-controller"
  repository = "https://aws.github.io/eks-charts"
  chart      = "aws-load-balancer-controller"
  version    = "1.11.0"
  namespace  = "kube-system"

  set {
    name  = "clusterName"
    value = aws_eks_cluster.main.name
  }

  set {
    name  = "serviceAccount.create"
    value = "false"
  }

  set {
    name  = "serviceAccount.name"
    value = kubernetes_service_account.load_balancer_controller.metadata.0.name
  }
}

これで terraform apply を実行すると、周辺のリソースの作成、クラスタの作成、アドオンの設定、そして Helm Chart のインストールまですべて一発で行われます。

terraform output を実行して、ArgoCD の URL を確認し、ブラウザでアクセスすれば、ArgoCD のダッシュボードが表示されるはずです!

途中でつまづいたこと

Load Balancer Controller のエラー、VPC ID を見つけられない

一向に Load Balancer Controller が起動しないと思っていたら、次のログが出力されていました。

{"level":"error","ts":"xxxx-xx-xxTxx:xx:xxZ","logger":"setup","msg":"unable to initialize AWS cloud","error":"failed to get VPC ID: failed to fetch VPC ID from instance metadata: error in fetching vpc id through ec2 metadata: get mac metadata: operation error ec2imds: GetMetadata, canceled, context deadline exceeded"}

このエラー文でググると次の記事が見つかり、マネージドノードのテンプレート側で hop limit を 2 に設定することで解決しました。
https://zenn.dev/danimal141/articles/ff0e603bf21af2

https://github.com/defaultcf/get-started-eks-in-2025/blob/300ea1267e29a6c5dfcd20c584847f3d8c022f13/infra/eks.tf#L51

Load Balancer Controller のエラー、サブネットを見つけられない

Load Balancer Controller の Pod で次のエラーを見つけました。

Failed build model due to couldn't auto-discover subnets: unable to resolve at least one subnet (0 match VPC and tags: [kubernetes.io/role/elb])

こちらの記事を参考に、サブネットのタグに次のように設定することで解決しました。

https://zenn.dev/not75743/scraps/b57073dc374af3

https://github.com/defaultcf/get-started-eks-in-2025/blob/300ea1267e29a6c5dfcd20c584847f3d8c022f13/infra/vpc.tf#L32-L35


いかがでしたか?
Terraform の AWS プロバイダーと Kubernetes プロバイダーを使うことで、EKS のデプロイから Helm Chart のインストールまで、再現性のあるデプロイが可能であることを示しました。

最後に terraform destroy をお忘れなく!

本記事が誰かの役に立つことを願っています🙏
お読みいただき、ありがとうございました!

サイボウズ 生産性向上チーム 💪

Discussion