はじめに
きちんとした Web サービスを展開しようと思ったとき、大手クラウドプロバイダーの AWS の上で、可用性の高い Kubernetes (K8s) を動かす (= EKS) という選択はよく挙がるパターンだと思います。
そうなると Terraform で EKS クラスターを IaC 化していきたいですよね。
しかし、難易度が高そう…。
そもそも Kubernetes 自体が難しいですし、それを AWS で動かすとなるとプロバイダー特有の知識が必要なうえ、必然的にネットワーク・セキュリティの難しさが乗っかってきます。
その状態でさらに、ドメインで公開するためには拡張機能まで投入しないといけないの…?
正直かなり高度な印象を受けてしまいます。
ただ、色々調べまくった結果、今は各所の努力のおかげでかなり少ないコードで実現できることが分かりました。
今回のコンセプトは「できるだけ簡単」です。
せっかくなので、ここにまとめておきたいと思います。
用語の説明
自分の理解の範囲になってしまいますが、それぞれ簡単に説明しておきます。
EKS Auto Mode
各種設定が自動化された EKS です。
大きなところとして、必須もしくは頻出アドオンが最初から組み込まれています。
ここでデカいなと感じるのは、ロードバランサーコントローラー、つまり AWS Load Balancer Controller が入っていることです。これは通常の EKS ではアドオンとしてすら存在しておらず、EKS クラスター上で Helm などで手動インストールする必要があるのですが、EKS Auto Mode ではその必要がありません。
また、Karpenter も組み込まれていてオートスケーリングの準備が整っています。オートスケーリングを利用しないにしても、インスタンスタイプを意識の外に追いやることができるのでメリットを享受できます。
かなりのマネージド感を浴びることができますね。
反面、個人的にかなり気になるデメリットとしてはインスタンス当たりの利用金額が高くなることです。

個人レベルで小さく運用するだけなら気にならない増分なのですが、仕事で大規模なサービス用だったりするとスケールアウトにより無視できないコストアップになる可能性があり、受け入れてもらいにくそうなのがしんどいです。
もしここが改善されたら大きなプロジェクトでも相当導入しやすくなるのですが…。
EKS Pod Identity
Pod に AWS アクセス権を付与する機能です。
同じ目的の機能で IAM roles for service accounts (IRSA) というものがありますが、EKS Pod Identity が後発でより使いやすくなっており、特別な理由がない限り EKS Pod Identity が推奨されるようです。それであれば使わない手はないですね。
ポイントは EKS Auto Mode には EKS Pod Identity Agent アドオンが組み込まれていることです。
つまり設定不要で EKS Pod Identity を使うことができます。
ExternalDNS
Kubernetes SIGs が提供する一つで DNS プロバイダーと自動で連携してくれる機能です。
AWS で言うと、Route 53 にレコードを自動設定してくれるようになります。
さて、EKS には ExternalDNS が外部アドオンとして存在します。
つまり Terraform コードに少しの行を追加するのみで使う準備が整うわけですね。
Terraform コード
全体を GitHub にアップロードしておきましたので、必要に応じて参照してください。
まずは EKS のコードを描いていきます。
おなじみ terraform-aws-modules/eks/aws モジュールを使います。
module “eks” を作成
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.37"
cluster_name = "example-eks"
cluster_version = "1.33"
cluster_endpoint_public_access = true
enable_cluster_creator_admin_permissions = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
cluster_compute_config = {
enabled = true
node_pools = ["general-purpose"]
}
}
cluster_compute_config
の部分が EKS Auto Mode を利用するための設定です。
EKS Managed Node Group のときに書いていた必須アドオンやインスタンス設定の記載を省略できています。
次に ExternalDNS をアドオンとして追加するコードを書きます。
本来 EKS Pod Identity と言えど、辛い IAM ロールの設定コードを書かなければならないのですが……
なんと eks-pod-identity という Terraform モジュールがあり、これは一般的に想定される IAM ポリシーを内部にもっている優れものです。
どうせ公式ドキュメントから探して JSON コピペするだけなんだから簡単に設定できるようになってくれないかなぁ(個人の感想です)という思いにピンポイントで応えてくれます。
留意点としては eks モジュールのアドオン側でロールを割り当てることです。
よく分からないまま eks-pod-identity モジュール側でも割り当ててしまうとクラスターに設定されてバッティングして apply に失敗します。私のように…。
module “eks” 内に追加
cluster_addons = {
external-dns = {
pod_identity_association = [
{
role_arn = module.external_dns_pod_identity.iam_role_arn
service_account = "external-dns"
}
]
}
}
module “external_dns_pod_identity” を作成
module "external_dns_pod_identity" {
source = "terraform-aws-modules/eks-pod-identity/aws"
version = "1.12.1"
name = "example-eks-external-dns"
attach_external_dns_policy = true
external_dns_hosted_zone_arns = ["arn:aws:route53:::hostedzone/*"]
# associations は指定しない
# EKS アドオン (eks.cluster_addons.external-dns) 側で指定するため
}
最終的なコードはこんな感じになります。短い!
これを terraform apply してみると、コンソール上で EKS クラスターができていることが確認でき、

アドオンに ExternalDNS が追加されています。ロールも割り当てられています。


おわりに
どうでしょう?かなりコードが少なく済んだのではないでしょうか?
同じような組み合わせを目指している方の参考になれば幸いです。
コメント