EKSで参照権限のみを与える

## やりたいこと

EKSでは[クラスターのユーザーまたは IAM ロールの管理](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html)に記載されているように、クラスタ作成者以外が kubectl コマンドを使うなどして Kubernetes API を叩くためには、aws-auth.yaml に以下のような改修を入れて IAM ユーザに権限を付与する必要がある。

```aws-auth.yaml
省略
  mapUsers: |
    - userarn: arn:aws:iam::AWSアカウントID:user/naotoshi.seo
      username: admin
      groups:
        - system:masters
```

system:masters は強い権限であり、kubernetes cluster を操作する全ての権限が付与される。

事故防止などの理由により、参照権限だけを付与したいことがある。その方法を調べた。

## やりかた

[デフォルトRoleとClusterRoleBinding](https://kubernetes.io/ja/docs/reference/access-authn-authz/rbac/#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88role%E3%81%A8clusterrolebinding) にあるように system:masters は cluster-admin ロールと紐付いている。
view クラスタロールが最初から存在するが、それに紐付いている ClusterRoleBinding がないだけなので、それを自分で作れば aws-auth.yaml で使える。

|デフォルトのClusterRole|デフォルトのClusterRoleBinding|
|---|---|
|cluster-admin|*system:masters* group|
|admin|None|
|edit|None|
|view|None|


aws-auth.yaml で利用できるように ClusterRoleBinding `cluster-viewer-view` (例えば) を作った。

```cluster-viewer.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: cluster-viewer-view
subjects:
- kind: Group
  name: cluster-viewer
  apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
```

FYI: なお view クラスタロールの権限確認は以下のコマンドでできる(長いので出力は省略)

```bash
$ kubectl get clusterrole/view -o yaml
```

あとは system:masters の代わりに作った ClusterRoleBinding の Group を指定すれば良い (ClusterRoleBinding 名ではなく Group 名なので注意)

```aws-auth.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::AWSアカウントID:role/EKSノードグループのインスタンスロール
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    - userarn: arn:aws:iam::AWSアカウントID:user/naotoshi.seo
      username: naotoshi.seo
      groups:
        # - system:masters
        - cluster-viewer # ココ
```

## おまけ: 追加の権限を与える

例えば port-forward ぐらいであれば環境破壊はされないので、権限付与しても良いというようなケースを考える。

port-forward に必要な RBAC を（なんとか）調べて、ClusterRole とそれに紐づく ClusterRoleBinding を作成する。

```yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: cluster-port-forwarder
rules:
# port-forward
- apiGroups:
  - ""
  resources:
  - pods/portforward
  verbs:
  - get
  - list
  - create
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: cluster-port-forwarder-cluster-port-forwarder
subjects:
- kind: Group
  name: cluster-port-forwarder
  apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-port-forwarder
```

あとは aws-auth.yaml の groups 指定に作った ClusterRoleBinding の Group を指定すれば良い

```aws-auth.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::AWSアカウントID:role/EKSノードグループのインスタンスロール
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    - userarn: arn:aws:iam::AWSアカウントID:user/naotoshi.seo
      username: naotoshi.seo
      groups:
        # - system:masters
        - cluster-viewer
        - cluster-port-forwarder # ココ
```