Amazon EKS on サービスアカウントの IAMロール

# サービスアカウント

Pod 内のコンテナから各リソースへのアクセス制御の際に用いられる。


# サービスアカウントの IAMロール

IAM ロールをサービスアカウントと関連付けて、サービスアカウントを使用するように Pod を設定する。

***要するに、Pod 単位で IAM ロールを割り当てることができる!!!***


# 手順

大まかな流れ

1. クラスター用の IAM OIDC プロバイダーを作成
2. IAM ロールを引き受けるための サービスアカウントの設定
3. サービスアカウントを使用するように Pod を設定する

## 1. クラスター用の IAM OIDC プロバイダーを作成

クラスターには、**OIDC 発行者 URL** が関連付けられています。
サービスアカウントで IAM ロールを使用するには、クラスターの OIDC 発行者 URL に対して **IAM OIDC プロバイダー**が存在している必要があります。

EKS クラスターのコンソール画面より
![スクリーンショット 2023-11-25 18.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/1e6bb29e-311d-8ac7-4074-bdbf84d79ae2.png)

IAM ID プロバイダの画面より
![スクリーンショット 2023-11-25 18.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/7d767d95-25e1-ea8b-0111-e8ab089e88b1.png)

IAM OIDC プロバイダーが作成されていない場合は、以下のドキュメントを参考に作成します。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/enable-iam-roles-for-service-accounts.html

私の場合は、`withOIDC: true`を指定しましたので IAM OIDC プロバイダーは既に作成されているようです。

```cluster-fargate.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: cluster-fargate
  region: ap-northeast-1
  version: "1.27"

iam:
  withOIDC: true

fargateProfiles:
  - name: fp-default
    selectors:
      - namespace: default
      - namespace: kube-system
```
## 2. IAM ロールを引き受けるための サービスアカウントの設定

IAM ロールを引き受けるように サービスアカウントを設定します。
任意の Pod はサービスアカウントを使用するように設定すると、IAM ロールにアクセス許可がある AWS のサービスにアクセスすることができるようになります。

### IAM ポリシー

まず、Pod が S3 にアクセスできるようにするための、IAM ポリシーを作成します。S3 全てに対してのアクション許可としてあります。

```iam-policy-test.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}
```

```
aws iam create-policy --policy-name iam-policy-test --policy-document file://iam-policy-test.json
```

```json
{
    "Policy": {
        "PolicyName": "iam-policy",
        "PolicyId": "ANPAT5BUXK4UJ23HFCNAJ",
        "Arn": "arn:aws:iam::123456789012:policy/iam-policy-test",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2023-11-25T09:39:58+00:00",
        "UpdateDate": "2023-11-25T09:39:58+00:00"
    }
}
```

### IAM ロールを作成し、サービスアカウントに関連付け

```
eksctl create iamserviceaccount --name service-account-test --namespace default --cluster cluster-fargate --role-name iam-role-test \
    --attach-policy-arn arn:aws:iam::111122223333:policy/iam-policy-test --approve
```

### IAM ロールの作成を確認

```
aws iam get-role --role-name iam-role-test --query Role.AssumeRolePolicyDocument
```

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/E42985489456BC67E825EFF4E0699XXX"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "oidc.eks.ap-northeast-1.amazonaws.com/id/E42985489456BC67E825EFF4E0699XXX:sub": "system:serviceaccount:default:service-account-test",
                    "oidc.eks.ap-northeast-1.amazonaws.com/id/E42985489456BC67E825EFF4E0699XXX:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}
```

### サービスアカウントを確認

```
kubectl describe sa service-account-test 
```

```
Name:                service-account-test
Namespace:           default
Labels:              app.kubernetes.io/managed-by=eksctl
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/iam-role-test
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>
```

## 3.サービスアカウントを使用するように Pod を設定する

Pod で作成したサービスアカウントを指定するには
`spec.serviceAccountName` に作成済のサービスアカウントを指定します。

```deployment-sa-test.yaml
apiVersion: v1
kind: Pod

metadata:
  name: awscli
  labels:
    app: awscli

spec:
  serviceAccountName: service-account-test
  containers:
  - image: amazon/aws-cli
    command:
      - "sleep"
      - "604800"
    imagePullPolicy: IfNotPresent
    name: awscli
  restartPolicy: Always
```

```
kubectl apply -f deployment-sa-test.yaml
```

```
deployment.apps/app-test created
```

# 動作確認

作成済のサービスアカウントを指定している場合

```
kubectl exec awscli -- aws s3 ls
```

```
2023-09-19 08:10:14 cdk-XXX
2023-11-16 00:54:31 cf-XXX
```

`spec.serviceAccountName`を指定していない場合

```
kubectl exec awscli -- aws s3 ls
```

```
Unable to locate credentials. You can configure credentials by running "aws configure".
command terminated with exit code 253
```