Amazon EKS - アクセスエントリ

# アクセスエントリ

Kubernetes クラスタへの IAM プリンシパルのアクセスを管理するための新しいコントロールセット。
特定の IAM プリンシパルに EKS アクセスポリシーを直接関連付けることで操作を行う。


# 利用可能な EKS アクセスポリシー

IAM プリンシパルに付与可能な EKS アクセスポリシーは以下の通りです。

```json
aws eks list-access-policies
{
    "accessPolicies": [
        {
            "name": "AmazonEKSAdminPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy"
        },
        {
            "name": "AmazonEKSClusterAdminPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
        },
        {
            "name": "AmazonEKSEditPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy"
        },
        {
            "name": "AmazonEKSViewPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
        }
    ]
}
```

|ポリシー|説明|
|---|---|
|AmazonEKSClusterAdminPolicy|クラスター管理者|
|AmazonEKSAdminPolicy|管理者|
|AmazonEKSEditPolicy|編集|
|AmazonEKSViewPolicy|表示|

# アクセスエントリを使用するには

アクセスエントリを使用するには**クラスターの認証モード**を `API_AND_CONFIG_MAP` または `API` にする必要があります。

|クラスターの認証モード|メソッド|
|---|---|
|ConfigMap only(CONFIG_MAP)|aws-auth ConfigMap|
|EKS API and ConfigMap (API_AND_CONFIG_MAP)|EKS API、AWS CLI、AWS SDK、AWS CloudFormation、AWS Management Console、aws-auth ConfigMap のアクセスエントリ|
|EKS API only (API)|EKS API、AWS CLI、AWS SDK、AWS CloudFormation、AWS Management Console、aws-auth|


# 検証準備

ざっくりと検証してみたいと思います。

## ClusterConfig

クラスター作成時に、`accessConfig` を次の通り作成していきます。

```ClusterConfig.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

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

iam:
  withOIDC: true

fargateProfiles:
  - name: fargate-default
    selectors:
      - namespace: default
      - namespace: kube-system
      - namespace: dev-1

  - name: fargate-test
    selectors:
      - namespace: prd-1

accessConfig:
  authenticationMode: API_AND_CONFIG_MAP
  accessEntries:
    - principalARN: arn:aws:iam::123456789012:role/eks-view-role
      accessPolicies:
        - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy
          accessScope:
            type: namespace
            namespaces:
              - default
              - dev-*

    - principalARN: arn:aws:iam::123456789012:role/eks-admin-role
      accessPolicies:
        - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
          accessScope:
            type: cluster
```

```
kubectl apply -f ClusterConfig.yaml
```

## Namespace

dev-1 と prd-1 という Namespace を作成しておきます。

```namespace.yaml
kind: Namespace
apiVersion: v1

metadata:
  name: dev-1

---

kind: Namespace
apiVersion: v1

metadata:
  name: prd-1
```

```
kubectl apply -f namespace.yaml
```

## Deployment

dev-1 の Namespaces に deployment を作成しておきます。

```deployment.yaml
apiVersion: apps/v1
kind: Deployment

metadata:
  name: nginx-deployment
  namespace: dev-1

spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
```

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

## IAM ロール

ec2 を Principal として 2 つの IAM ロールを準備しておきます。

|IAM ユーザー or IAM ロール|
|---|
|arn:aws:iam::123456789012:role/eks-view-role|
|arn:aws:iam::123456789012:role/eks-admin-role|

*なお、EKS アクセスポリシーによって IAM principal に付与されるアクセスは、IAM principal に関連付けられた IAM ポリシーによって定義されたアクセス許可とは別のものであることに注意してください。*


## Cloud9

動作検証は Cloud9 から行いますので、Cloud9 を起動し、eksctl と kubectl のインストール、kubeconfig ファイルを作成します。

eksctl のインストール

https://eksctl.io/installation/

kubectl のインストール

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html

kubeconfig ファイルの作成

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/create-kubeconfig.html

```
aws eks update-kubeconfig --region ap-northeast-1 --name cluster-demo
```


# 動作確認

## eks-view-role での動作確認

Cloud9 に 先程作成した IAM ロール eks-view-role をアタッチして動作確認をしていきます。
なお、Cloud9 に IAM ロールをアタッチする方法は下記サイトをご確認ください。

https://dev.classmethod.jp/articles/execute-aws-cli-with-iam-role-on-cloud9/

eks-view-role はクラスター作成時に以下の通り作成しました。
特定の namespaces に対してのみへの読み取り権限です。

```yaml
    - principalARN: arn:aws:iam::123456789012:role/eks-view-role
      accessPolicies:
        - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy
          accessScope:
            type: namespace
            namespaces:
              - default
              - dev-*
```

確認する動作は以下 3 つです。

① dev-1 に pod が起動していることが確認できること。
② prd-1 で pod の確認ができないこと。
③ dev-1 で deployment の削除ができないこと。

```①.
kubectl get pod -n dev-1
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-57d84f57dc-6fvzb   1/1     Running   0          2m45s
nginx-deployment-57d84f57dc-w8wrd   1/1     Running   0          2m45s
```

```②.
kubectl get pod -n prd-1
Error from server (Forbidden): pods is forbidden: User "arn:aws:sts::123456789012:assumed-role/eks-view-role/i-0ea7d2118d0064640" cannot list resource "pods" in API group "" in the namespace "prd-1"
```

```③.
kubectl delete -f deployment.yaml 
Error from server (Forbidden): error when deleting "deployment.yaml": deployments.apps "nginx-deployment" is forbidden: User "arn:aws:sts::123456789012:assumed-role/eks-view-role/i-0ea7d2118d0064640" cannot delete resource "deployments" in API group "apps" in the namespace "dev-1"
```

## eks-admin-role での動作確認

Cloud9 に 先程作成した IAM ロール eks-admin-role をアタッチして動作確認をします。

eks-admin-role はクラスター作成時に以下の通り作成しました。
クラスター管理者としての権限です。

```yaml
    - principalARN: arn:aws:iam::123456789012:role/eks-admin-role
      accessPolicies:
        - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
          accessScope:
            type: cluster
```

④ dev-1 の deployment が削除できることを確認

```
kubectl delete -f deployment.yaml 
deployment.apps "nginx-deployment" deleted
```


# リンク

https://eksctl.io/usage/access-entries/

https://aws.amazon.com/jp/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/access-entries.html