概要
EKS Pod Identityを活用したASCP(AWS Secrets and Configuration Provider)の設定手順をハンズオン形式で解説します。
なぜやった方がいい?
- EKS Pod IdentityでOIDCプロバイダー設定を不要に
→ EKSにおけるIAM認証を簡素化し、セキュリティを強化 - ASCPはSecrets ManagerのシークレットをPod内のファイルとしてマウント
→ アプリケーションコードの変更なしに機密情報を利用できます。 - Pod Identityの使用により、IAMロールを複数のEKSクラスターで再利用可能
→ 複数クラスターの運用負荷が軽減されます。
言葉の説明
EKS Pod Identity vs. IRSA (IAM Roles for Service Accounts)
EKSにおいて、PodにAWSリソースへのアクセス権限を付与する主要な方法は、1. IRSA と 2. EKS Pod Identity の2つがあります。
AWSは現在、EKS Pod Identityの使用を推奨しています。
| 比較項目 | IRSA (従来の方式) | EKS Pod Identity (推奨方式) |
|---|---|---|
| 認証メカニズム | OIDC Provider + STS AssumeRoleWithWebIdentity を使用して一時認証情報を取得。 | EKS Auth API + Pod Identity Agent (各ノードのDaemonSet) 経由で一時認証情報を取得。 |
| OIDC Provider | クラスターごとに設定が必要。 | 不要 |
| IAMロールの信頼ポリシー | クラスターごとのOIDCプリンシパルを参照する必要がある。 | 単一のサービスプリンシパル pods.eks.amazonaws.com を信頼するだけ |
| ロールの再利用性 | ロールを別のクラスターで使う際、信頼ポリシーの更新が必要。 | 信頼ポリシーを更新することなく、複数のクラスターで同じIAMロールを使用可能 |
| アクセス制御 | IAMポリシーを使用。 | ロールセッションタグ(クラスター名、Pod名など)を用いたきめ細かなABAC(属性ベースのアクセス制御)が可能 |
| 必要バージョン | EKS 1.17+ | EKS 1.24+ |
ASCP (AWS Secrets and Configuration Provider) の役割
ASCPは、KubernetesのSecrets Store CSI DriverのAWS向けプロバイダーです。
AWS Secrets Managerのシークレットや、AWS Systems Manager Parameter Store のパラメータを、Kubernetes Pod内のボリュームにファイルとしてマウントします。

↓↓引用元
従来のシークレット取得との違い:
- アプリケーションはAWS SDKを使用せず、通常のファイル読み取り(File I/O)で機密情報にアクセスできます。
→ 特にレガシーアプリケーションや、シークレット取得用のカスタムコードを書きたくない場合に互換性を提供します。 - シークレットをJSON形式で格納している場合でも、ASCPはJMESPath構文を使用して、特定のキーと値のペアだけを選択的にPodにマウントできます。
- セキュリティ考慮事項: ASCPはPod内のファイルシステムにシークレットを保存するため、セキュリティを重視するアプリケーションでは、ネイティブなAWS APIを使用してシークレットをメモリにキャッシュすることが依然として推奨されます。
ハンズオンやってみよう
前提条件
本ハンズオンは、以下の環境を対象とします。
| 項目 | 詳細 |
|---|---|
| EKSクラスター | バージョン 1.24 以降 で作成済みであること。 |
| ノードグループ | Amazon EC2 ノードグループを使用していること。 |
| ツール | kubectl、aws cli、eksctl、および helm (v3.0以降) がインストール済みであること。 |
| 説明を省略する範囲 | EKSクラスターの作成、VPC/サブネットの設定、AWS CLI認証情報は完了しているものとします。 |
FargateではDaemonSet(Agent)のインストールは不要(または不可)ですが、本ハンズオンの手順はEC2ノードを前提としています。
手順 (ASCP + EKS Pod Identity 連携)
EKSクラスターにASCPをインストールし、Pod Identityを介してSecrets Managerのシークレットを取得する手順です。
ステップ 1: コンポーネントのインストール
1-1. Secret Store CSI Driver と ASCP プロバイダーのインストール
ASCPのHelmチャートは、互換性のあるSecrets Store CSI Driverを依存関係として自動的にインストールします。
# 1. ASCP Helmリポジトリを追加
helm repo add aws-secrets-manager https://aws.github.io/secrets-store-csi-driver-provider-aws
# 2. ASCPをインストール (CSI Driverも自動インストールされる)
helm install -n kube-system secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws
1-2. EKS Pod Identity Agent アドオンのインストール
Pod Identityを使用するため、Agentアドオンをクラスターにインストールします。
REGION=<EKSクラスターのリージョン名>
CLUSTERNAME=<EKSクラスター名>
eksctl create addon --name eks-pod-identity-agent --cluster "$CLUSTERNAME" --region "$REGION"
ステップ 2: IAMロールと関連付けの設定
2-1. シークレットとIAMポリシーの準備
テスト用のシークレットを作成し、そのシークレットにアクセスするためのIAMポリシーを定義します。
SSMパラメータストアを使用する場合は ssm:GetParameters 権限が必要です。
# テストシークレットの作成 (例)
aws --region "$REGION" secretsmanager create-secret --name MySecret --secret-string '{"username":"testuser", "password":"testpassword"}'
IAMアクセス許可ポリシーの定義と作成します。
XXXを含むResourceには、先ほど作成したテストシークレットのARNを入れてください。
{
"Statement": [
{
"Action": [
"secretsmanager:ListSecrets",
"secretsmanager:BatchGetSecretValue"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"secretsmanager:ListSecretVersionIds",
"secretsmanager:GetSecretValue",
"secretsmanager:GetResourcePolicy",
"secretsmanager:DescribeSecret"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:ap-northeast-1:XXXX:secret:MySecret-XXXX"
]
},
{
"Action": "kms:Decrypt",
"Effect": "Allow",
"Resource": "arn:aws:kms:*:*:key/*"
}
],
"Version": "2012-10-17"
}
2-2. Pod Identity用IAMロールの作成
IAMロール(ロール名:nginx-pod-identity-role)を作成し、信頼ポリシーにEKS Pod Identityのサービスプリンシパル(pods.eks.amazonaws.com)を設定します。
aws iam create-role --role-name nginx-pod-identity-role --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "pods.eks.amazonaws.com" },
"Action": [ "sts:AssumeRole", "sts:TagSession" ]
}
]
}'
作成したアクセス許可ポリシーをロールにアタッチ。
# POLICY_ARNは作成したポリシーのARNを入れてください
POLICY_ARN=XXXXX
aws iam attach-role-policy \
--role-name nginx-pod-identity-role \
--policy-arn $POLICY_ARN
2-3. Pod Identity Association(関連付け)の作成
IAMロールとKubernetesサービスアカウントを関連付けます。
# サービスアカウント 'nginx-sa' を作成し、IAMロールに関連付ける
# ROLE_ARNは作成したロールのARNを入れてください
ROLE_ARN=XXXXX
eksctl create podidentityassociation \
--cluster "$CLUSTERNAME" \
--namespace default \
--region "$REGION" \
--service-account-name nginx-sa \
--role-arn $ROLE_ARN \
--create-service-account true
ステップ 3: SecretProviderClassとPodのデプロイ
3-1. SecretProviderClassの定義
usePodIdentity: "true" を設定してPod Identity経由での認証を明示し、マウントするシークレットを指定します。
ASCPプラグインのバージョンが古いと動作しない可能性があります。
# secretproviderclass-pod-identity.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secrets-pod-identity
spec:
provider: aws
parameters:
# EKS Pod Identity の利用を明示
usePodIdentity: "true"
objects: |
- objectName: "MySecret"
objectType: "secretsmanager"
適用コマンド
kubectl apply -f secretproviderclass-pod-identity.yaml
3-2. Podのデプロイと検証
PodにSecretProviderClassをボリュームとしてマウントし、シークレットがファイルとして取得できているか確認します。
ファイル名はSecret名と同じになります。
# deployment-pod-identity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pod-identity-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
serviceAccountName: nginx-sa # ステップ2-3で作成したサービスアカウント
containers:
- name: nginx
image: public.ecr.aws/nginx/nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: secrets-store-volume
mountPath: "/mnt/secrets-store" # シークレットがマウントされるパス
readOnly: true
volumes:
- name: secrets-store-volume
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "aws-secrets-pod-identity" # ステップ3-1で作成したリソース
# 適用
kubectl apply -f deployment-pod-identity.yaml
# 検証
POD_NAME=$(kubectl get pods | awk '/nginx-pod-identity-deployment/{print $1}' | head -1)
# シークレットがファイルとしてマウントされていることを確認
kubectl exec -it $POD_NAME -- cat /mnt/secrets-store/MySecret
Pod Identity Agentのログを確認することで、認証やマウントのトラブルシューティングが可能です。
最後に
Pod IdentityとIRSAの違いの一つとして、K8sのService Accountの設定値も変わります。
IRSAの場合
kubectl describe saで表示される内容の中に、アノテーションのiam-roleが含まれます
> kubectl describe sa example-service-account
Name: aws-load-balancer-controller
Namespace: kube-system
Labels: app.kubernetes.io/managed-by=eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXX:role/XXXXXXX-role
# 以下略...
K8sがIAMとService Accountの紐付けを管理していることになります。
Pod Identityの場合
上記アノテーションは表示されません。その代わり、aws eks list-pod-identity-associationsで表示されます。
> aws eks list-pod-identity-associations --cluster-name=example-cluster
{
"associations": [
{
"clusterName": "example-cluster",
"namespace": "kube-system",
"serviceAccount": "example-service-account",
"associationArn": "arn:aws:eks:ap-northeast-1:XXXXXXXXXX:podidentityassociation/example-cluster/XXXXXXXXXX",
"associationId": "XXXXXXXXXX"
},
# 以下略...
これは、IAMとServicAccountの紐付け管理する場所が、K8sからAWSへ移行されているためです。
デバッグの時はご注意ください。
参考資料リスト