EKSのサービスアカウント作成時に複数のポリシーを割り当てる
目的
EKSにおいてPodごとにアクセスできるAWSサービスを限定したい際に利用するIRSAですが、
複数のポリシーを1つのRoleおよびサービスアカウントに紐づける方法があるか検証してみます。
結論
eksctl create iamserviceaccountで事前に定義済みのRoleを紐づけることで、
複数のポリシーを1つのRoleおよびサービスアカウントに紐づけることができました。
最終的な構成は以下の通りです。
手順
0. サービスアカウントの動作確認用画面疎通
最終的に作成したサービスアカウントが正しく機能するかどうか、動作確認するためにサービスアカウントなしの状態でエラーが発生することを確認します。
今回の環境はIntroduction to Amazon EKSで作成した環境を利用しています。
上記ハンズオンにおいてIRSAが設定されていない(backendアプリにDynamoDB周りのポリシーが割り当たっていない)状態だと、以下の画面に遷移します。
1. 任意のポリシーを作成する。
今回はマネコン上から任意のポリシーを3つ作成しました。
ここで作成するポリシーはIntroduction to Amazon EKSのIAM Roles for Service Accountsで利用するDynamoDBのポリシーを3つに分解したものです。
バックエンドサービスにこのポリシーを付与することで、0.で確認したエラーを回避できます。
2. OIDCプロバイダーの作成
eksctlでOICDプロバイダーを作成します。
$ eksctl utils associate-iam-oidc-provider \
--cluster ekshandson \
--approve
2022-12-23 10:28:19 [ℹ] will create IAM Open ID Connect provider for cluster "ekshandson" in "us-east-1"
2022-12-23 10:28:19 [✔] created IAM Open ID Connect provider for cluster "ekshandson" in "us-east-1"
3. 任意のRoleを作成する。
eksctl create iamserviceaccountでサービスアカウントに紐づけるRoleを作成します。
ここではRoleに対して1.で作成したポリシーを関連付けるとともに、信頼ポリシーも編集します。
信頼ポリシーの編集は作成するRoleを紐づけ先のサービスアカウントから利用できるようにするために行います。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "[2.で作成したOIDCプロバイダーのArn]"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"[プロバイダ]:aud": "sts.amazonaws.com",
"[プロバイダ]:sub": "system:serviceaccount:backend:[サービスアカウント名]"
}
}
}
]
}
4. サービスアカウントの作成
いよいよeksctlでサービスアカウントを作成します。
通常、--atache-policy-arnを使用することによって、--atache-policy-arnで割り当てたポリシーが設定されたIAM Roleが作成され、eksctlコマンドで作成されたサービスアカウントと関連付けられます。
3.で信頼ポリシーを設定しましたが、eksctlコマンドでRoleごと作成してしまう場合は、自動的に信頼ポリシーを設定してくれるためユーザ自身で定義する必要はありません。
今回は事前定義済みのRoleとサービスアカウントを関連付けるため、--atache-role-arnで関連付けるRoleを直接指定します。
$ eksctl create iamserviceaccount --name my-service-account --namespace backend --cluster ekshandson --attach-role-arn arn:aws:iam::[アカウントID]:role/Role --approve
2023-09-18 02:35:20 [ℹ] 1 existing iamserviceaccount(s) (backend/dynamodb-messages-access) will be excluded
2023-09-18 02:35:20 [ℹ] 1 iamserviceaccount (backend/my-service-account) was included (based on the include/exclude rules)
2023-09-18 02:35:20 [!] serviceaccounts that exist in Kubernetes will be excluded, use --override-existing-serviceaccounts to override
2023-09-18 02:35:20 [ℹ] 1 task: { create serviceaccount "backend/my-service-account" }
2023-09-18 02:35:20 [ℹ] created serviceaccount "backend/my-service-account"
以下のコマンドで作成されたサービスアカウントが確認できます。
Annotationsでattach-role-arnに指定した、RoleのArnが記載されていることが確認できます。
$ kubectl describe serviceaccount my-service-account -n backend
Name: my-service-account
Namespace: backend
Labels: app.kubernetes.io/managed-by=eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::[アカウントID]:role/Role
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
5. deployment.yamlの修正
podsにサービスアカウントを関連付けるため、deployment.yamlにserviceAccountNameを追記します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
selector:
matchLabels:
app: backend
replicas: 2
template:
metadata:
labels:
app: backend
spec:
+ serviceAccountName: my-service-account
containers:
- name: backend
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/backend:latest
imagePullPolicy: Always
ports:
- containerPort: 5000
env:
- name: AWS_DEFAULT_REGION
value: us-east-1
- name: DYNAMODB_TABLE_NAME
value: messages
6. デプロイ
deployment.yamlの変更を環境に反映します。
$ kubectl apply -f backend-deployment.yaml -n backend
deployment.apps/backend configured
無事デプロイに成功し、0.で確認した画面に再度アクセスしたところ、期待する画面が表示されました!
うまくいかなかったときはこちら
再作成コマンドはこちら
$ kubectl rollout restart deploy backend
IRSAのトラブルシューティングには以下のページを利用しました。
まとめ
事前定義済みのRoleをサービスアカウントに関連付けることで、複数のポリシーをサービスアカウントに紐づけることができました。
ただし、eksctl create iamserviceacountでRoleを作ってしまったほうが、信頼ポリシーを編集する手間がないのでお手軽に感じました。
Discussion