EKSインストールやってみよう
参考サイト
私はよく理解していないかったので
参考サイトのファイルを置いて
以下のコマンドを実行します。
terraform init
AI回答
terraform init を実行したタイミングで、それらのプロバイダー(通訳プログラム)が自動的にダウンロードされます。
terraform initが実行された後、行われること
1.コードの解析:
Terraformがあなたの書いた .tf ファイルを読み、「AWSを操作するんだな」「Kubernetesも使うんだな」と判断します。
2.ダウンロード:
必要なプロバイダーを Terraform Registry(公式の配布場所)から探して、現在のディレクトリにある .terraform という隠しフォルダの中にダウンロードします。
3.ロックファイルの作成:
terraform.lock.hcl というファイルを作り、「今回はこのバージョンをダウンロードしたよ」という記録を残します。
なぜこれが表示されるのか
terraform version を打ったときにそれらが表示されるのは、「すでに init が完了していて、手元にそのバージョンのプロバイダーが存在しているから」です。
補足:もしコードを書き換えて新しいプロバイダーを追加したら?
新しいプロバイダー(例えば google や helm など)をコードに追加した場合は、もう一度 terraform init を叩く必要があります。そうしないと、「新しいプロバイダーが手元にないよ!」とエラーが出て plan や apply が実行できません。
terraformのバージョン確認方法①
# terraform version
Terraform v1.14.8
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.37.0
+ provider registry.terraform.io/hashicorp/cloudinit v2.3.7
+ provider registry.terraform.io/hashicorp/kubernetes v2.14.0
+ provider registry.terraform.io/hashicorp/tls v4.2.1
Your version of Terraform is out of date! The latest version
is 1.15.1. You can update by downloading from https://developer.hashicorp.com/terraform/install
terraformのバージョン確認方法②
# terraform -v
Terraform v1.14.8
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.37.0
+ provider registry.terraform.io/hashicorp/cloudinit v2.3.7
+ provider registry.terraform.io/hashicorp/kubernetes v2.14.0
+ provider registry.terraform.io/hashicorp/tls v4.2.1
Your version of Terraform is out of date! The latest version
is 1.15.1. You can update by downloading from https://developer.hashicorp.com/terraform/install
インストール時に使ったコマンドとファイル
以下の部分はバージョンを変更しています。
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/install/iam_policy.json
今回はhelmでのインストールしています。
(cert-managerはインストールしていません)
# helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=tf-eks-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set enableCertManager=false
結果
NAME: aws-load-balancer-controller
LAST DEPLOYED: Tue May 5 16:51:15 2026
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!
このタイミングで、AWS Load Balancer controllerがkube-system上に存在する
#確認したほうがいいと思う
#kubectl get pods
一部ファイル修正(バージョンの問題?)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-tf-eks
annotations:
# ここにスペース2つ分のインデントを入れてください
alb.ingress.kubernetes.io/scheme: internet-facing
spec:
ingressClassName: alb
rules:
- http:
paths:
- backend:
service:
name: web-tf-eks
port:
number: 80
path: /
pathType: Prefix
resource "kubernetes_service_account" "aws_loadbalancer_controller" {
metadata {
name = "aws-load-balancer-controller"
namespace = "kube-system"
annotations = {
"eks.amazonaws.com/role-arn" = module.iam_assumable_role_admin.iam_role_arn
}
}
(EKS&terraformがど素人なので)記載している内容の意味がわからないところをAI先生に聞きながら理解していく
resource "kubernetes_service_account" "aws_loadbalancer_controller"
設定の意味
1.Terraformで記述されたこのリソースは、Kubernetesの ServiceAccount(サービスアカウント) を作成する定義です。
2.Kubernetesクラスター内に「Podが使うID(ServiceAccount)」を作成します。
3."eks.amazonaws.com/role-arn" = module.iam_assumable_role_admin.iam_role_arn
ここがEKS独自の仕組みである IRSA (IAM Roles for Service Accounts) の肝です。
このアノテーションを付けることで、Kubernetes上のこのServiceAccountと、AWS側の IAMロール(ポリシーを詰め込んだもの) が「合体」します。
もう少し深い説明
疑問
なんでこんな名前(eks.amazonaws.com/role-arn)にAWSのロールを入れるんだろう?
回答
これは AWS(EKSの開発チーム) があらかじめ決めたルールです。
Kubernetesの世界には、標準機能以外にも「独自の拡張機能」を追加できる仕組みがあります。AWSは「ServiceAccountに eks.amazonaws.com/role-arn という名前の注釈があったら、それはIAMロールとの紐付けだと解釈する」というプログラムをEKSの中に組み込んでいます。
例えるなら、
「専用の振込用紙にある『指定の記入欄』」 のようなものです。
ServiceAccount: 振込用紙
eks.amazonaws.com/role-arn: 「振込先口座番号」という項目名(あらかじめ印刷されている)
IAMロールのARN: あなたが実際に書き込む口座番号
さらに番外編
この部分はすごくややこしいので再度記載
resource "kubernetes_service_account" "ここ(A)" {
metadata {
name = "ここ(B)"
namespace = "kube-system"
}
}
(A)"aws_loadbalancer_controller"【自由】
Terraformのプログラム内でこのリソースを指すための名前です。
他のコードと合わせる必要はありません。
(B)name = "aws-load-balancer-controller"【厳密に合わせる!】
Helmコマンド で指定した --set serviceAccount.name=... の名前と、1文字も違わずに合わせる必要があります。
これが一致していないと、Helmで入れた作業員(Pod)が「自分のIDが見つからない!」とエラーになります。
一般的には、混乱を避けるために (A)と(B)を似たような名前にしておく のがインフラエンジニアの「お作法」です。
例えば、
Terraform内の名前(A)は aws_lb_controller (アンダースコア)
実際の名前(B)は aws-load-balancer-controller (ハイフン)
のようにしておけば、Terraformが管理しやすくなります。
まとめ:
resource のすぐ横の名前は、自分(Terraform)が管理しやすい名前でOK です。
設定確認方法
Kubernetes側での確認(アノテーションの確認)
kubectl get sa aws-load-balancer-controller -n kube-system -o yaml
Pod側での確認(権限の注入確認)
kubectl get pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller -o yaml | grep AWS_ROLE_ARN
以下の理由説明
module "iam_assumable_role_admin" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 4.0"
create_role = true
role_name = var.role_aws_load_balancer_controller
provider_url = replace(module.eks.cluster_oidc_issuer_url, "https://", "")
role_policy_arns = [aws_iam_policy.aws_loadbalancer_controller.arn]
oidc_subjects_with_wildcards = ["system:serviceaccount:*:*"]
}
1行づつかみ砕いて
どんな名前でもOK
「 "iam_assumable_role_admin"」
モジュール名を決めるだけ。識別名(ローカル名)
# あなたがわかりやすい名前であればOK
module "iam_assumable_role_admin" {
では次
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 4.0"
terraform-aws-modules/iam/aws:
「AWSのIAMに関するモジュール集」という大きなパッケージを指します。世界中のエンジニアが使っている、非常に信頼性の高いデファクトスタンダード(標準的)なテンプレートです。
//modules/iam-assumable-role-with-oidc:
その大きなパッケージの中にある、「OIDCを使ってIAMロールを借りる(Assumable)ための専用ツール」をピンポイントで指定しています。
~> 4.0 の意味:
「4.0 以上、5.0 未満」という意味になります。
なぜこう書くかというと、「バグ修正などの小さなアップデート(4.1, 4.2...)は自動で取り入れたいけど、使い方がガラッと変わる大きな変更(5.0以上)は勝手に入れないでほしい」という、安全のための指定方法です。
ちなみに「//」が気になる人もいるかと思います。
Terraformにおける「ここから先はサブディレクトリ(中身のフォルダ)
左側 (terraform-aws-modules/iam/aws)
これは「リポジトリ(大きな倉庫)」の場所です。Terraformはまず、この単位でファイルをまるごとダウンロードします。
右側 (modules/iam-assumable-role-with-oidc)
ダウンロードした大きな倉庫の中にある、「特定のフォルダ」を指しています。
さて次
provider_url = replace(module.eks.cluster_oidc_issuer_url, "https://", "")
AI回答
EKSクラスター固有の ID プロバイダー(OIDC)を指定しています。「うちの EKS クラスターから来たリクエストなら信じていいよ」と AWS IAM に教えている設定です。
OIDCの確認方法
1.EKSの画面: 「クラスター」→ 自分のクラスター名を選択 → 「概要」タブ
そこに 「OpenID Connect プロバイダー URL」 という項目があり、https://amazonaws.com... のようなURLが載っています。
これが「EKSクラスター固有のID」の実体です。
AWS IAM側の設定ルールで、
「IDプロバイダーを指定するときは、頭の https:// は取って書かなければいけない」という決まりがあるからです。
そのためにreplace
2.aws cliでの確認方法
aws eks describe-cluster --name <クラスター名> --query "cluster.identity.oidc.issuer" --output text
では次
oidc_subjects_with_wildcards = ["system:serviceaccount:*:*"]
AI回答
system:serviceaccount: 「これは Kubernetes の ServiceAccount ですよ」という定型句。
- (1つ目): Namespace(名前空間)の名前。
- (2つ目): ServiceAccount 自体の名前。
具体的に記載すると
本来、セキュリティを厳しくするなら以下のようにピンポイントで書くのが理想です。
"system:serviceaccount:kube-system:aws-load-balancer-controller"
(=kube-system フォルダにある、aws-load-balancer-controller 君だけに貸します)
Podがリクエスト: 「ALBを作りたい!」
AWS IAMがチェック: 「君は誰?」「私は kube-system の aws-load-balancer-controller です」
IAMの判断: 「設定(:)を見ると、誰でもOKと書いてあるな。よし、権限を貸そう」
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web-tf-eks
name: web-tf-eks
spec:
replicas: 2
selector:
matchLabels:
app: web-tf-eks
strategy: {}
template:
metadata:
labels:
app: web-tf-eks
spec:
containers:
- image: nginx:latest
name: web-tf-eks
---
apiVersion: v1
kind: Service
metadata:
name: web-tf-eks
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: web-tf-eks
type: NodePort
以下の意味
AI回答
appsグループ(APIグループ (apps)にDeployment、StatefulSet、DaemonSet なども含まれる)
v1 は安定版(GA: General Availability)であることを意味します。
apiVersion: apps/v1
deploymentの場合の調査方法
kubectl api-versions
kubectl api-resources | grep deployments
AI回答
kindの下のmetadataについて
「Deployment(管理役)そのもの」に名前やラベルを付ける場所です。
kind: Deployment
metadata:
kind: Deployment
metadata:
name: web-tf-eks # Deployment自体の本名
labels: # Deployment自体に貼る付箋(タグ)
app: web-tf-eks
以下のコマンドで情報取得可能
kubectl get deployment
それでは以下の解説
spec:
replicas: 2
selector:
matchLabels:
app: web-tf-eks
AI回答
spec(望ましい状態): ユーザーが「こうあってほしい」とお願いする内容。
replicas: 2「このPodを常に 2つ 動かしておいてね」
selector: matchLabels: ...:「Deploymentが管理する対象のPodをどうやって見つけるか」というルール
この後に出てくる template: 内で定義するPodのラベルと、この matchLabels が一致していないとエラーになるので注意が必要です
では次
strategy: {}
AI回答
strategy: {} は、Podをアップデートする際の「切り替え手順(戦略)」を指定する場所です。
AI回答
デフォルトでRollingUpdate(デフォルト)
古いPodを1つずつ消しながら、新しいPodを1つずつ作っていく方式。
サービスを止めずに(無停止で) アップデートできます。
細かい挙動(一度にいくつまで増やしていいか等)をカスタマイズしたい時に、この strategy 欄に詳細を書きます。
Recreate
今ある古いPodを一度すべて削除してから、新しいPodを一斉に作る方式。
一時的にサービスが停止しますが、「新旧のバージョンが混ざると不具合が起きる」という場合に選ばれます。
では次
template:
metadata:
labels:
app: web-tf-eks
AI回答
template:の意味は、Podの設計図(雛形)
「ここから下は、Deploymentが新しく作るPodの設定ですよ」という境界線が template: です。
template: の下には必ず以下の2つを書きます。
metadata:(Podの管理情報)
ここでラベルを付けます。
「これから作るPodにはこの名前(ラベル)を貼る」という指示です。
spec:(Podの具体的な中身)
ここでコンテナイメージ、ポート、メモリ制限などを書きます。
「これから作るPodの中ではこのアプリを動かす」という指示です。
これは、Deploymentが新しく作り出すPodに貼り付ける「名札(ラベル)」を定義しています。
ラベルを貼る (template.metadata.labels)
「これから作るPodには app: web-tf-eks という名札を貼っておいてね」と指示しています。
紐付ける (selector.matchLabels)
Deploymentは、この名札を頼りに「あ、このPodは私が管理する担当の子だ!」と見分けます。
では次
spec:
containers:
- image: nginx:latest
name: web-tf-eks
AI回答
image: nginx:latest
Docker Hubなどから持ってくるコンテナイメージの指定です。
ECRとか持ってくる場合:image: ://amazonaws.com
name: web-tf-eks
Podの中で動くコンテナ自体の名前です。
1つのPodの中に複数のコンテナを入れることもあるので(サイドカー構成など)、それらを区別するために名前を付けます。
ポートとメモリ制限の書き方
containers:
- name: web-tf-eks
image: ://amazonaws.com
ports:
- containerPort: 80 # コンテナがリッスンするポート
resources:
requests:
memory: "64Mi" # 最低限確保するメモリ
cpu: "250m" # 最低限確保するCPU (0.25コア)
limits:
memory: "128Mi" # これ以上使わせない上限
cpu: "500m" # これ以上使わせない上限
サイドカー構成
containers:
- name: main-app
image: nginx:latest
- name: sidecar-log-collector
image: fluentd:latest # 例:ログを集める補助コンテナ
そして次
apiVersion: v1
kind: Service
metadata:
name: web-tf-eks
Service名の定義をmetadata:の中でおこなっている
AI回答わかりやすく
ports:
- port: 80 # ① Service自身のポート(窓口の番号)
targetPort: 80 # ② Podのポート(送り先の番号)
protocol: TCP
selector:
app: web-tf-eks
selector(セレクター)は、一言で言うと「このサービスが、どのPod(アプリケーションの実体)に通信を届けるべきか?」を決めるための検索条件のようなものです。
selector(Service側): 「app: web-tf-eks というタグがついたPodを探せ」という命令。
labels(Pod/Deployment側): 「自分は app: web-tf-eks というタグを持っている」という自己紹介。
以下が結構ややこしい
type: NodePort
AI回答
実にややこしい
1.ユーザー → ALB: 80番ポートでアクセス
2.ALB → EC2: 31567番ポートで転送(※ここがNodePortの役割)
3.EC2内部: 31567番に届いた通信を、自動的に Service の 80番へ送り届ける
今回は設定していないが
type: ClusterIPでもできるらしい。
流れ: ALB → PodのIPアドレス へ直接(ダイレクトに)送信
※最近はこちらが主流みたい
NodePort: ALBが「EC2という箱」を目指して通信を送る場合に必要。
ClusterIP: ALBが「Podという中身」を直接狙って通信を送る場合に使える。
NodePortが必要な場合:
alb.ingress.kubernetes.io/target-type: instance
ClusterIPでOKな場合:
alb.ingress.kubernetes.io/target-type: ip
次のお題目
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::xxxxxxxxxxx:role/tf-eks-node-group-xxxxxxxxxxxxxxxx
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
# 以下を追加
mapUsers: |
- userarn: arn:aws:iam::xxxxxxxxxxx:user/xxxxxx
username: xxxxxx
groups:
- system:administrator
この役割
この aws-auth という ConfigMap は、「AWSの権限(IAM)」と「Kubernetes内部の権限」を紐付けるための名簿のような役割をしています。
AWSのIAMユーザーやIAMロールは、そのままではKubernetesを操作する権限を持っていません。このConfigMapに登録することで初めて、Kubernetesが「このIAMユーザーは、うちのクラスターの管理者として認めよう」と認識できるようになります。
では解説
metadata:
name: aws-auth
namespace: kube-system
両方この名前でないとNGらしい。
Amazon EKSにおいて、aws-auth という名前は特別です。EKSの裏側にある認証システムが「aws-auth という名前の ConfigMap に書いてある名簿を見て、アクセスを許可するか決めよう」とあらかじめ決めているため、この名前を 1文字でも変えてしまうと機能しません。
Kubernetesの中には複数の名前空間がありますが、kube-system はクラスターの動作に不可欠な「システム用の最重要エリア」です。
mapRoles: |
- rolearn: arn:aws:iam::xxxxxxxxxxx:role/tf-eks-node-group-...
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
役割: ワーカーノード(EC2インスタンス)をクラスターに参加させるための設定です。
意味: 「このIAMロールを持つEC2インスタンス(ノード)は、クラスターを構成する仲間(nodes)として扱います」という宣言です。
これが正しく設定されていないと、ノードを起動しても kubectl get nodes で NotReady になったり、表示されなかったりします。
では次
# 以下を追加
mapUsers: |
- userarn: arn:aws:iam::xxxxxxxxxxx:user/xxxxxx
username: xxxxxx
groups:
- system:administrator
役割: 指定した IAMユーザー に Kubernetes を操作する権限を与えます。
userarn: 権限を与えたいAWS上のIAMユーザーの識別番号です。
username: Kubernetes内部でそのユーザーをどう呼ぶか(任意ですが、IAMユーザー名と同じにするのが一般的です)。
groups: そのユーザーにどのレベルの権限を与えるか。
system:masters(またはご提示の administrator 相当のグループ)に所属させると、クラスターに対する全権限(管理者権限)を持つことになります。
ちなみに
Kubernetesには RBAC (Role-Based Access Control) という権限管理の仕組みがありますが、system:masters というグループは、最初から「すべての操作を許可する」という設定(ClusterRoleBinding)が内部でハードコーディングされています。
そのため、このグループに所属させたユーザーは、設定を特に追加しなくても、あらゆるリソース(Pod, Service, ConfigMapなど)の作成・削除・変更ができるようになります。
どんな「定義(Role/ClusterRole)」確認コマンド
# クラスター全体の全権限一覧を表示
kubectl get clusterroles
# 特定の権限(例:admin)の詳細をYAMLで見る
kubectl get clusterrole admin -o yaml
# 全体の紐付け一覧を表示
kubectl get clusterrolebindings
# 特定の紐付け(例:先ほどの system:masters 関連)の詳細を見る
kubectl get clusterrolebinding cluster-admin -o yaml
AWS Load Balancer Controllerのインストール
方法は2つある
・helmでのインストール
・ソースからのインストール
そもそもこの二つの違いとは
AI回答
Linuxのわかる人には
「Kubernetes界のyum(dnf)やapt」と例えるのが最も正確で分かりやすい。
単位:チャート (Chart)
※rpmみたいなものかな
helmのrepoが登録済みであること
# helm repo list
NAME URL
eks https://aws.github.io/eks-charts
まだの方は
helm repo add eks https://aws.github.io/eks-charts
helmで「aws-load-balancer-controller」をインストール
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=tf-eks-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set enableCertManager=false
意味の理解
--set enableCertManager=false
前提として
AWS Load Balancer Controllerを動作させるために証明書が必要になる。
なぜ「証明書」が必要なのか?
AWS Load Balancer Controller は、Kubernetesの内部で「Webhook」という仕組みを使って、設定に間違いがないかチェック(バリデーション)を行います。この内部通信を安全に行うために、TLS証明書(HTTPSのような鍵)が必要になります
enableCertManager=false にするとどうなる?
以前の主流(true): cert-manager という別の有名なソフトをあらかじめクラスターに入れておき、そいつに証明書の発行・更新を任せていました。
今の主流(false): コントローラー自身が自分で証明書を作って管理するようになりました。
ソースからのインストール方法は以下の手順になる
#以下に説明記載
curl -Lo ingress-controller.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v3.2.2/v3_2_2_full.yaml
#自分のクラスタ名に変更する
sed -i.bak -e 's|your-cluster-name|${CLUSTER_NAME}|' ./ingress-controller.yaml
AI回答
・コントローラーを動かすためのすべてのリソースが詰まった「全部入りパック」です。
この中には以下のものが含まれています:
・Deployment: コントローラー本体(プログラム)をどのPodで動かすか。
・ServiceAccount / ClusterRole / RoleBinding: コントローラーがAWSのAPIを叩いたり、クラスター内の情報を読み取るための「権限設定」。
・CustomResourceDefinitions (CRD): ALB固有の設定(TargetGroupBindingなど)をKubernetesが理解できるようにするための「新しい言葉の定義」。
次に
curl -Lo ingclass.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v3.2.2/v3_2_2_ingclass.yaml
ファイルの中身
apiVersion: elbv2.k8s.aws/v1beta1
kind: IngressClassParams
metadata:
labels:
app.kubernetes.io/name: aws-load-balancer-controller
name: alb
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/name: aws-load-balancer-controller
name: alb
spec:
controller: ingress.k8s.aws/alb
parameters:
apiGroup: elbv2.k8s.aws
kind: IngressClassParams
name: alb
これは、IngressClass というリソースを定義するファイルです。
Kubernetesに対して、「alb という名前の Ingress 設定が来たら、AWS Load Balancer Controller が担当してください」という紐付けを登録します。
トラブルシューティング時に使用するコマンド
名前空間とラベルを指定してpodの状態確認
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
podの状態確認
kubectl describe pod <pod-name> -n kube-system
endpointsの状態確認
kubectl get endpoints -n kube-system aws-load-balancer-webhook-service
iamなどの権限変更時に再起動
※ダウンタイムなし。
※podの作り替え
kubectl rollout restart deployment aws-load-balancer-controller -n kube-system
ingressの状態確認
kubectl get ingress
tail版
kubectl get ingress -w
podのログを確認
以下のようにすると同じラベルのログがまとめて確認できる。すごい
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
tail版
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller --tail=50
特定のingress確認コマンド
kubectl describe ingress ingress-tf-eks
ロールにアタッチされているポリシー一覧を表示
aws iam list-attached-role-policies --role-name EKSIngressAWSLoadBalancerControllerRole
現在のポリシーの最新バージョンIDを取得
VERSION=$(aws iam get-policy --policy-arn arn:aws:iam::xxxxxxxxx:policy/EKSIngressAWSLoadBalancerControllerPolicy --query 'Policy.DefaultVersionId' --output text)
ポリシーのJSON中身を表示
aws iam get-policy-version --policy-arn arn:aws:iam::xxxxxxxxx:policy/EKSIngressAWSLoadBalancerControllerPolicy --version-id $VERSION
AWS Load Balancer ControllerをEKSにインストール
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=tf-eks-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set enableCertManager=false