はじめに
2025年に発表されたEKSの新機能「EKS Capabilities」の内容がとても興味深いものだったので実際にやってみました!
特に業務でも使用していたArgoCDがAWSマネージドな機能として利用可能となる旨の記載を見て、これは!と思いました。
というのも、業務でEKS上に自分でArgoCDをセットアップした際は、色々とエラーにあたって一苦労した思い出があり、EKS Capabilitiesによって誰でも簡単に高速にArgoCDが使えるようになるのではないかと考えたからです。
更に調べていくと、ACKという機能も業務で苦労したAWS Load Balancer Controllerの代替として使えるのではと思い、ますます実際に使ってみたくなりました。
というわけでハンズオンやっていきます。
前提
今回はCloudFormationでEKSを作成し、EKS Capabilitiesのハンズオンはマネジメントコンソール上で行うこととします。
EKSは業務でも使用していたFargateで動かします。(もし業務でCapabilitiesを入れたらという具体的なイメージをつけるためにできる限り環境は寄せたいため)
注意点
このハンズオンはコストが発生しますので、もしご自身でも実施される場合はその旨予めご了承ください。
CloudFormationスタックでEKSや必要リソースを一括作成、削除可能になっているので、1日程度でハンズオン完了してスタック削除してしまえばそこまで高コストにはならない想定です。
ArgoCDハンズオンの流れ
1. IaCテンプレートを使用して、CloudFormationスタックを作成
スタックの作成は、こちらのハンズオンの記事を参考にしてください
AWSTemplateFormatVersion: "2010-09-09"
Description: "Simple EKS on Fargate (Hands-on) + VPC (2AZ / Public+Private / NAT) - Capabilities are set at deploy time."
Parameters:
System:
Description: System Name
Type: String
Environment:
Description: Environment Name
Type: String
ClusterName:
Type: String
Default: "hands-on-eks-fargate"
Description: "EKS Cluster Name"
KubernetesVersion:
Type: String
Default: "1.34"
Description: "EKS Kubernetes version (must be supported in your region/account)"
VpcCidr:
Type: String
Default: "10.0.0.0/16"
PublicSubnet1Cidr:
Type: String
Default: "10.0.0.0/24"
PublicSubnet2Cidr:
Type: String
Default: "10.0.1.0/24"
PrivateSubnet1Cidr:
Type: String
Default: "10.0.10.0/24"
PrivateSubnet2Cidr:
Type: String
Default: "10.0.11.0/24"
EndpointPublicAccess:
Type: String
Default: "true"
AllowedValues: ["true", "false"]
Description: "EKS API endpoint public access"
EndpointPrivateAccess:
Type: String
Default: "true"
AllowedValues: ["true", "false"]
Description: "EKS API endpoint private access"
Resources:
# -----------------------------
# VPC
# -----------------------------
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${ClusterName}-vpc"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${ClusterName}-igw"
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# -----------------------------
# Subnets (2AZ / Public+Private)
# -----------------------------
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: !Ref PublicSubnet1Cidr
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${ClusterName}-public-az1"
# EKS向けタグ(LB等で利用)
- Key: kubernetes.io/role/elb
Value: "1"
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [1, !GetAZs ""]
CidrBlock: !Ref PublicSubnet2Cidr
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${ClusterName}-public-az2"
- Key: kubernetes.io/role/elb
Value: "1"
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: !Ref PrivateSubnet1Cidr
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub "${ClusterName}-private-az1"
- Key: kubernetes.io/role/internal-elb
Value: "1"
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [1, !GetAZs ""]
CidrBlock: !Ref PrivateSubnet2Cidr
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub "${ClusterName}-private-az2"
- Key: kubernetes.io/role/internal-elb
Value: "1"
# -----------------------------
# Routing (Public: IGW / Private: NAT)
# -----------------------------
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${ClusterName}-rtb-public"
PublicRoute:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
NatEip:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub "${ClusterName}-nat-eip"
NatGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatEip.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: !Sub "${ClusterName}-natgw"
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${ClusterName}-rtb-private-az1"
PrivateDefaultRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NatGateway
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${ClusterName}-rtb-private-az2"
PrivateDefaultRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NatGateway
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
# -----------------------------
# Security Group (Cluster)
# -----------------------------
EKSClusterSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "EKS Cluster Security Group (hands-on)"
VpcId: !Ref VPC
SecurityGroupEgress:
- IpProtocol: "-1"
CidrIp: "0.0.0.0/0"
Tags:
- Key: Name
Value: !Sub "${ClusterName}-eks-sg"
# -----------------------------
# IAM Roles (EKS Cluster / Fargate Pod Execution)
# -----------------------------
EKSClusterRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${ClusterName}-EKSClusterRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: eks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
- arn:aws:iam::aws:policy/AmazonEKSVPCResourceController
FargatePodExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${ClusterName}-FargatePodExecutionRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: eks-fargate-pods.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy
# -----------------------------
# CloudWatch Logs (optional but handy)
# -----------------------------
EKSClusterLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/aws/eks/${ClusterName}/cluster"
RetentionInDays: 7
# -----------------------------
# EKS Cluster
# -----------------------------
EKSCluster:
Type: AWS::EKS::Cluster
DependsOn:
- VPCGatewayAttachment
- EKSClusterLogGroup
Properties:
Name: !Ref ClusterName
Version: !Ref KubernetesVersion
RoleArn: !GetAtt EKSClusterRole.Arn
Logging:
ClusterLogging:
EnabledTypes:
- Type: api
- Type: audit
- Type: authenticator
- Type: controllerManager
- Type: scheduler
AccessConfig:
AuthenticationMode: API_AND_CONFIG_MAP
ResourcesVpcConfig:
SecurityGroupIds:
- !Ref EKSClusterSecurityGroup
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
EndpointPublicAccess: !Ref EndpointPublicAccess
EndpointPrivateAccess: !Ref EndpointPrivateAccess
# -----------------------------
# Fargate Profiles
# - kube-system は CoreDNS などに必須
# -----------------------------
FargateProfileDefault:
Type: AWS::EKS::FargateProfile
DependsOn: EKSCluster
Properties:
ClusterName: !Ref ClusterName
FargateProfileName: "fp-default"
PodExecutionRoleArn: !GetAtt FargatePodExecutionRole.Arn
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Selectors:
- Namespace: default
FargateProfileKubeSystem:
Type: AWS::EKS::FargateProfile
DependsOn:
- EKSCluster
- FargateProfileDefault
Properties:
ClusterName: !Ref ClusterName
FargateProfileName: "fp-kube-system"
PodExecutionRoleArn: !GetAtt FargatePodExecutionRole.Arn
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Selectors:
- Namespace: kube-system
FargateProfileArgoCD:
Type: AWS::EKS::FargateProfile
DependsOn:
- EKSCluster
- FargateProfileKubeSystem
Properties:
ClusterName: !Ref ClusterName
FargateProfileName: "fp-argocd"
PodExecutionRoleArn: !GetAtt FargatePodExecutionRole.Arn
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Selectors:
- Namespace: argocd
使用するパラメータ:
ClusterName: "eks-handson" ※任意の値
KubernetesVersion: "1.34" ※2026年1月時点の最新Ver
VpcCidr: "10.0.0.0/16"
PublicSubnet1Cidr: "10.0.0.0/24"
PublicSubnet2Cidr: "10.0.1.0/24"
PrivateSubnet1Cidr: "10.0.10.0/24"
PrivateSubnet2Cidr: "10.0.11.0/24"
EndpointPublicAccess: "true"
EndpointPrivateAccess: "true"
2. ArgoCD機能の作成
作成されたEKSクラスターの機能タブを開き、「機能を作成」を押下

「ArgoCDロールを作成」を押下し、ArgoCD用のIAMロールを作成

自動でEKS Capabilitiesが選択されているので、「次へ」を押下

必要なポリシーは自動でアタッチされている
ロール名や説明を変更可能
問題なければ、「ロールを作成」を押下

IAMアイデンティティセンターが必須ですが、私の環境では作成したことがなかったので、
「IAMアイデンティティセンターへ移動」を押下

以下の公式ドキュメントを参考に、有効化
「IAM Identity Center のアカウントインスタンスを有効に」を押下
※ベストプラクティスはAWS Organizationsで有効化のため注意、今回はPoCのためアカウントインスタンスを有効にする

作成されたグループを開き、「ユーザーをグループに追加」を押下

入力したメールに招待メールが来るので、「Accept invitation」を押下
PWを設定する

メール内にAWS access portal URLがあるので、押下しサインインしておく(この後ArgoCD GUIに入る際に必要なため)※ユーザー名/PW入力、MFAの登録が必要、手順は割愛

EKSの画面に戻る(ページ自体を更新しないと、作成したグループが表示されなかったため、F5で更新してください)
先ほど作成したグループを選択し、今回は管理者ロールを割り当て
(ほかにもエディタ、ビューワーロールあり)
名前空間(namespaces)はデフォルトのargocdのままで良い
「次へ」を押下

※もしうまくいかない場合は、IAMアイデンティティセンターで作成したユーザーでAWS access portalにサインしているかを確認してください
3. ArgoCDにEKSクラスターを登録
まずCloud ShellからEKSを操作できるようにするために、自身のIAMユーザーをEKSのアクセスエントリに追加し権限を付与する必要がある
CloudShellで以下のコマンドを実行
aws eks create-access-entry \
--cluster-name eks-handson \
--principal-arn arn:aws:iam::<AWSアカウントID>:user/<IAMユーザー名> \
--region <リージョン> || true
aws eks associate-access-policy \
--cluster-name eks-handson \
--principal-arn arn:aws:iam::<AWSアカウントID>:user/<IAMユーザー名> \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy \
--access-scope type=cluster \
--region <リージョン>
アクセスエントリに自身のIAMが追加されていることを確認
(今回はPoCのためIAMユーザーを登録しましたが、IAMロールを登録することも可能)

CloudShellを開き、以下のコマンドを実行(kubeconfig設定)
aws eks update-kubeconfig --name <EKSクラスター名> --region <リージョン名>
試しに以下のようにkubectlコマンドを実行して正常応答あれば成功

CloudShell上で、以下のコマンドを実行し、クラスターをArgoCDに登録するためのSecret作成YAMLを作成
vi argocd-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: eks-handson
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
stringData:
name: eks-handson
server: arn:aws:eks:<リージョン名>:<AWSアカウントID>:cluster/<EKSクラスター名>
project: default
※serverにはAPIエンドポイントURLではなく、EKSクラスターのARNを指定する旨公式ドキュメントで注釈があったため注意
以下コマンドでSecretを作成
kubectl apply -f argocd-secret.yaml
ステータスがSuccessfulになることを確認(何かApplicationを作成した後に確認する)

4. ArgoCDアクセスエントリRBAC設定
ArgoCDの機能を作成すると自動でアクセスエントリが作成されるが、デフォルトではKubernetes RBAC権限は付与されない。(最小権限の原則に従う)
クラスター全体の読み取りアクセス、書き込みアクセスの権限付与が必要
CloudShellで以下のコマンドを実行
aws eks associate-access-policy \
--region <リージョン名> \
--cluster-name <EKSクラスター名> \
--principal-arn <ArgoCD Capabilities用に作成したIAMロールのARN> \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy \
--access-scope type=cluster
※ただし公式ドキュメントにあるように本番環境ではより権限を絞る必要あり、今回付与したのはあくまで検証や開発用の権限
5. GitHubリポジトリ連携
今回はCodeConnectionsを使用して、GitHubと連携し、GitOps化する
他にもGitHubのデプロイキーを使ってGitHubをArgoCDに登録するなど様々な連携方法あり
前提として、今回は既にCodeConnectionsでGitHubとAWSが連携されていることとする
設定方法は以下の記事が分かりやすいので参照
ArgoCD Capabilities用のIAMロールに以下のポリシーをアタッチ
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codeconnections:UseConnection",
"codeconnections:GetConnection"
],
"Resource": "arn:aws:codeconnections:region:account-id:connection/connection-id"
}
]
}
以下のコマンドを実行し、GitHub登録用のApplicationマニフェストを作成
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: github-connection
namespace: argocd
spec:
source:
repoURL: https://codeconnections.<リージョン名>.amazonaws.com/git-http/<AWSアカウントID>/<リージョン名>/<CodeConnectionsのID>/<GitHubのOwner>/<GitHubのリポジトリ名>.git
targetRevision: main
path: kubernetes/manifests
※RepoURLのサンプル
https://codeconnections.ap-northeast-1.amazonaws.com/git-http/111122223333/ap-northeast-1/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/github-owner/github-repos.git
(CodeConnectionsのIDはARNの末尾の数字の羅列、GitHub Owner/リポジトリは)
GitHub上でリポジトリを開いているときの「XXX/YYY」のXXXがOwner、YYYがリポジトリ名に該当)
CloudShellで以下のコマンド実行し、GitHub連携用のApplicationを作成
kubectl apply -f github-connection.yaml
5. GitHubにマニフェストを置いて、ArgoCDによって自動デプロイ
先ほどのApplicationを見るとエラーが発生している
内容としては、指定したパスにマニフェストが存在しない旨のエラー
そこで指定したパス配下にApplication用のマニフェストを配置し、動作を確認する
連携したGitHubに以下フォルダを作成
kubernetes/manifests
ブランチはmainを使用
※もしmainブランチ以外を使用したい場合は、先ほど手動でapplyしたマニフェストのtargetRevisionに使用したいブランチを指定して、再作成
kubernetes/manifests配下に以下マニフェストを作成
今回はtest-appというApplicationを作成し、簡単なServiceとDeploymentを自動デプロイする
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: test-app
namespace: argocd
spec:
project: default
source:
repoURL: https://codeconnections.<リージョン名>.amazonaws.com/git-http/<AWSアカウントID>/<リージョン名>/<CodeConnectionsのID>/<GitHubのOwner>/<GitHubのリポジトリ名>.git
targetRevision: main
path: kubernetes/manifests/test-app
destination:
server: <EKSクラスターのARN>
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
kubernetes/manifests配下にtest-appフォルダを作成し、その配下に以下のマニフェストを作成
簡単なnginx PodをデプロイするDeployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
上記Deploymentに紐づくService
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
type: ClusterIP
簡単に仕組みを説明すると、Applicationによって、DeploymentとServiceが作成されるように、ソースとなるGitHubの情報、参照するブランチ、パス、デプロイ先のEKSの情報をtest-application.yamlで定義している
今回はシンプルな構成にしたが、指定したパス(今回ならkubernetes/manifests/test-app/)配下にマニフェストを配置すれば、hpaやsecret等も作成可能、またkustomizeを使用して、環境ごとにoverlaysでパッチを当てたり、パス配下のどのマニフェストを対象とするかも制御可能)
上記の内容をmainブランチにpushする(PR→マージ等は各自のルールに合わせて実施してください)
数分待つと自動でデプロイされるので、ArgoCDのGUI上で確認
(mainブランチに変更があったことをArgoCDが検知して、環境に自動デプロイする)
ServiceとDeploymentが作成され、nginxのPodが1つ起動している!

ACKハンズオンの流れ
ArgoCDのハンズオンは一旦完了です
この後はACKを作成し、ArgoCDで自動デプロイしたKubernetsリソースによってAWSリソースが自動プロビジョニングされるかを試してみます
ACK用のロールを作成するため、「管理者ロールを作成」を押下
※今回はPoCのため管理者権限で作成するが、マネコンの注記にもあるように実際の業務では最小権限に設計する

ロール名等を任意の命名に変更可能
内容確認し、「ロールを作成」を押下

EKSクラスターのリソースタブより、拡張機能>CustomResourceDefinitions(CRD)を開き、CRDが追加されていることを確認

Podを外部に公開するためのALBをACKで作成してみる
まずはALB用のSGを作成
※ALBと同じテンプレート内で作成しようとしたが、ALBに紐づけるSGはIDの形で渡す必要あり、分割して作成
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: SecurityGroup
metadata:
name: alb-sg
namespace: default
spec:
name: alb-sg
description: "ALB Security Group created by ACK"
vpcID: <VPC ID>
ingressRules:
- ipProtocol: tcp
fromPort: 80
toPort: 80
ipRanges:
- cidrIP: <自端末のグローバルIPアドレス※確認くん等で確認する>
egressRules:
- ipProtocol: "-1"
ipRanges:
- cidrIP: 0.0.0.0/0
EKSのSGのインバウンドルールに作成されたALBからの通信を許可
ポート: 80
ソース: ALBのSG ID

GitHubリポジトリのkubernetes/manifests/test-app/配下に以下のマニフェストを作成
apiVersion: elbv2.services.k8s.aws/v1alpha1
kind: LoadBalancer
metadata:
name: test-alb
namespace: default
spec:
name: test-alb
type: application
scheme: internet-facing
ipAddressType: ipv4
# PublicサブネットのIDを指定
subnets:
- <Subnet1a ID>
- <Subnet1c ID>
securityGroups:
- <先ほど作成したALB用のSG ID>
---
apiVersion: elbv2.services.k8s.aws/v1alpha1
kind: TargetGroup
metadata:
name: test-tg
namespace: default
spec:
name: test-tg
targetType: ip
protocol: HTTP
port: 80
vpcID: <VPC ID>
healthCheckProtocol: HTTP
healthCheckPath: /
healthCheckPort: traffic-port
targets:
- id: <nginx PodのIPアドレス※確認方法は後述>
port: 80
---
apiVersion: elbv2.services.k8s.aws/v1alpha1
kind: Listener
metadata:
name: test-listener-80
namespace: default
spec:
loadBalancerRef:
from:
name: test-alb
port: 80
protocol: HTTP
defaultActions:
- type: fixed-response
fixedResponseConfig:
statusCode: "404"
contentType: text/plain
messageBody: "no rule matched"
---
apiVersion: elbv2.services.k8s.aws/v1alpha1
kind: Rule
metadata:
name: test-rule-echo
namespace: default
spec:
listenerRef:
from:
name: test-listener-80
priority: 10
conditions:
- field: path-pattern
pathPatternConfig:
values:
- "/*"
actions:
- type: forward
forwardConfig:
targetGroups:
- targetGroupRef:
from:
name: test-tg
weight: 1
※PodのIP確認方法
kubectl get pod -o wide
ArgoCDの自動デプロイ完了後、ALBおよび関連リソースが作成されていることを確認
※ruleのみout of syncステータス、差分としてはTargetGroupRefでTG名を指定しているが、実際のマニフェストにはTGのARNが指定されているという点、原因については要調査、一旦このハンズオンの中では問題ないため静観とした

ブラウザでコピーしたURLを開き、nginxのサンプルページが表示されることを確認

こちらでArgoCDおよびACKをEKS Capabilitiesで作成し、Kubernetes APIでKubernetesとAWSリソースどちらも作成、管理し、自端末からインターネット経由でPodへ接続するハンズオンができました!
ACKの挙動を確認する為に、削除もやってみます
先ほど配置したalb.yamlをGitHub上から削除し、ArgoCDの同期を待つと、、、
同様にSGも削除可能ですが、EKSのSGの許可ルールを削除してから実施して下さい

最後にハンズオンが完了したら、スタックを削除して下さい
実際に使ってみた感想
ArgoCDについて
ArgoCDについてはimageUpdaterが使えない等の制約はあるものの、業務で使用していたArgoCD(自前でEKS上にデプロイしている)と使用感は変わらずにそのまま利用することができました!
しかも何よりセットアップが簡単かつ、時間も短いです
業務のArgoCDはHelmインストール、そのためのvalues.yamlの作成や、ArgoCD GUI用のALBの作成、Route53にALBのレコードを登録、接続用のWorkspacesの払い出しetc...様々な作業工程があり、1つの環境でセットアップするのに最低でも3~4h程度かかっていました
また途中エラー等でうまくいかないこともあり、ある程度KubernetesやArgoCD周りの経験がある人が実施する必要がある点も考慮するとかなり大変です
それがEKS Capabilitiesを使用すると30分程度でArgoCDのセットアップを完了することができました!しかもさほどKubernetesやArgoCDの知識がない人でも、公式ドキュメント通りに実施していけば実施可能なくらい簡単にできるという印象です
今回は実施しませんでしたが、アカウントやリージョン等をまたいだマルチクラスター管理、リモートクラスター管理等もできそうな記述を公式ドキュメントで目にしたので色々と活用できそうという点でも今後も触っておきたいと思います!
ACKについて
これは完全に私の知識不足と事前の調査不足なのですが、AWS Load balancer Controllerを代替できるのかなと淡い期待を抱いて色々試してみたのですが、結論代替不可でした。。。
やはり従来のようにKubernetes APIでingress/serviceを作成し、AWS側にはALB/NLBをプロビジョニングして、連携する(ALBへのターゲットの自動登録等が可能)ということをやりたいときはAWS Load Balancer Controllerを使用する必要があります
ACKではALB自体の作成はできるものの、Pod(Service)を動的に紐づけて、Podが再作成されたら自動でIPをターゲットグループに登録しなおすといったことはできませんでした
そのため今回のハンズオンでは、手動でPodのIPを取得し、ALBのマニフェストに記述するというイレギュラーな構成となっています。(業務ではまずあり得ない構成なので参考にしないでください)
SGとALBを同じテンプレート内で作成、紐づけできない点も不便でした
とはいえ、Kubernetes API経由で簡単にAWSリソースが作成できる点はとても興味深かったです!
今回は実施していないですが、公式の例だとS3バケットやDynamoDB等も作成でき、その他いろいろなAWSサービスに対応していそうだなという印象を受けました
Kubernetesに完結した形で、開発者に必要なAWS/Kubernetesリソースを作成、管理、さらにそちらをArgoCDでGitOps化して自動デプロイするといった構成は、素早く開発環境を提供するときなどに役立ちそうだなーと思いました
具体的なユースケースを想像するだけでも楽しいですよね!
今回は実施していないKROも使えば、この辺りがさらに抽象化されて、簡素になるのかなと思っていますが、そちらの検証はまた追って実施します
まとめとしては、今後色々な課題の解決の1つのソリューションとして期待できそうという所感です
引き続きEKS Capabilitiesについては実際に触ってみながら、あわよくば業務で使用する機会をうかがいたいですね(より実践的なナレッジがたまったらまた発信します)
シンプルに触っていてめちゃくちゃ楽しかったです!
ここまで読んでいただきありがとうございました!
備忘録
引っかかりポイント
- 手動ApplyしたApplication(github-connections.yaml)ではServerはEKSクラスター名を指定して問題なかったが、GitOpsで自動作成させたApplication(test-application.yaml)ではEKSクラスター名を指定するとnot foundとなった
EKSのARNに変更すると正常に作成された
下記公式情報によると、EKSクラスター名、ARNどちらでもよく、可読性のためにクラスター名が推奨されていた
原因については引き続き調査する
今後のハンズオンのイメージ
- Capabilitiesの作成自体をIaC化できないかの検証
- KROのハンズオン
- より実践を想定して権限を最小権限で実施
参考サイト










































