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 に公開しています。
今必要なものは課金可能な AWS アカウントと mise だけです。
mise install
terraform init
terraform apply
どう実現しているの?
何も特別なことはしておらず、null resource すら使っていません。
秘訣は、Terraform の Kubernetes プロバイダーと Helm プロバイダーを使うだけです。
なんだそんなことか、と思われるでしょう。
ただ、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 に設定することで解決しました。
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])
こちらの記事を参考に、サブネットのタグに次のように設定することで解決しました。
いかがでしたか?
Terraform の AWS プロバイダーと Kubernetes プロバイダーを使うことで、EKS のデプロイから Helm Chart のインストールまで、再現性のあるデプロイが可能であることを示しました。
最後に terraform destroy
をお忘れなく!
本記事が誰かの役に立つことを願っています🙏
お読みいただき、ありがとうございました!
Discussion