EKSでRBACを利用したdeveloperの認証・認可を設定をする

# はじめに
Amazon EKSでRBACを利用した`developer`の認可設定をする方法をまとめます。
IAMグループに所属するIAMユーザーに、EKSクラスターの任意のNamespaceへのアクセス許可を付与します。
Mac環境を想定しています。

`admin`に関しては[EKSでRBACを利用したadminの認証・認可を設定をする](https://qiita.com/miyabiz/items/4c9db597e9eb70445b0b)を参考にしてください。

# 実行環境の準備
1.  AWS CLIの設定
[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

1.  EKSクラスタの構築
[Macでeksctlを利用してAmazon EKSのクラスターを構築する](https://qiita.com/miyabiz/items/75f83237795b0b7d52bd)を参考にしてください。

1.  EKSのコンテキストの設定
[MacにてAmazon EKSの設定をする](https://qiita.com/miyabiz/items/b98d145cedb35dab9524)を参考にしてください。

# IAMロールの作成

1.  IAMロールを作成する
    ※このIAMロールはEKSへのアクセス許可に利用します。
    ※今回はロール名を`akane-dev-eks-developer-role`にしています。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    DEV_ASSUME_ROLE_POLICY=$(echo -n '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "sts:AssumeRole",
          "Principal": {
              "AWS": "arn:aws:iam::'; echo -n "${ACCOUNT_ID}"; echo -n ':root"
          }
        }
      ]
    }')
    aws iam create-role \
      --role-name akane-dev-eks-developer-role \
      --assume-role-policy-document "${DEV_ASSUME_ROLE_POLICY}"
    ```

1.  IAMロール用のポリシーを作成する
    ※このIAMポリシーはKESのコンテキスト設定時にAWS CLIで`aws eks update-kubeconfig`が利用できるようにします。
    ※今回はポリシー名を`akane-dev-eks-developer-role-policy`にしています。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    DEV_ROLE_POLICY=$(echo -n '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "eks:DescribeCluster",
          "Resource": "arn:aws:eks:*:'; echo -n "${ACCOUNT_ID}"; echo -n ':cluster/*"
        }
      ]
    }')
    aws iam create-policy \
        --policy-name akane-dev-eks-developer-role-policy \
        --policy-document "${DEV_ROLE_POLICY}"
    ```

1.  IAMロール用のポリシーをIAMロールにアタッチする

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    aws iam attach-role-policy \
      --role-name akane-dev-eks-developer-role \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-developer-role-policy
    ```

# IAMグループの作成

1.  IAMグループを作成する
    ※今回はロール名を`akane-dev-eks-developer-group`にしています。

    ```sh
    aws iam create-group --group-name akane-dev-eks-developer-group
    ```

1.  IAMグループ用のポリシーを作成する
    ※今回はポリシー名を`akane-dev-eks-developer-group-policy`にしています。
    ※このポリシーが先ほど作成したIAMロールを委任(AssumeRole)します。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    DEV_GROUP_POLICY=$(echo -n '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "sts:AssumeRole",
          "Resource": "arn:aws:iam::'; echo -n "${ACCOUNT_ID}"; echo -n ':role/akane-dev-eks-developer-role"
        }
      ]
    }')
    aws iam create-policy \
        --policy-name akane-dev-eks-developer-group-policy \
        --policy-document "${DEV_GROUP_POLICY}"
    ```

1.  IAMグループ用のポリシーをIAMグループにアタッチする

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    aws iam attach-group-policy \
      --group-name akane-dev-eks-developer-group \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-developer-group-policy
    ```

# 環境設定
※事前にKubernetesクラスターのコンテキストの設定をします。

1.  `akane-namespace.yaml` を作成する
    ```yaml:akane-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: akane
    ```

1.  `akane-developer-role.yaml`を作成する

    ```yaml:akane-developer-role.yaml
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: dev-akane-developer-role
      namespace: akane
    rules:
      - apiGroups:
          - ""
          - "apps"
          - "batch"
          - "extensions"
        resources:
          - "configmaps"
          - "cronjobs"
          - "deployments"
          - "events"
          - "ingresses"
          - "jobs"
          - "pods"
          - "pods/attach"
          - "pods/exec"
          - "pods/log"
          - "pods/portforward"
          - "secrets"
          - "services"
        verbs:
          - "create"
          - "delete"
          - "describe"
          - "get"
          - "list"
          - "patch"
          - "update"
    ```

1.  `akane-role-developer-binding.yaml` を作成する

    ```yaml:akane-role-developer-binding.yaml
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: dev-akane-developer-role-binding
      namespace: akane
    subjects:
    - kind: User
      name: dev-akane-developer-user
    roleRef:
      kind: Role
      name: dev-akane-developer-role
      apiGroup: rbac.authorization.k8s.io
    ```

1.  クラスターに適用する

    ```sh
    kubectl apply -f akane-namespace.yaml
    kubectl apply -f akane-developer-role.yaml
    kubectl apply -f akane-developer-role-binding.yaml
    ```

1.  aws-auth ConfigMap を更新して、IAM ロールを許可する
    ※クラスター名を設定します。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    eksctl create iamidentitymapping \
      --cluster ${クラスター名} \
      --arn arn:aws:iam::${ACCOUNT_ID}:role/akane-dev-eks-developer-role \
      --username dev-akane-developer-user
    ```

1.  クラスターで管理されているすべての ID のリストを取得する

    ```sh
    eksctl get iamidentitymapping --cluster ${クラスター名}
    ```

# IAMユーザーの作成
1.  IAMユーザーを作成する
    ※今回はユーザー名を`eks-akane-developer`にしています。

    ```sh
    aws iam create-user --user-name eks-akane-developer
    ```

1.  IAMユーザーをIAMグループにアタッチする

    ```sh
    aws iam add-user-to-group \
      --user-name eks-akane-developer \
      --group-name akane-dev-eks-developer-group
    ```

1.  IAMユーザーのアクセスキーを作成する

    ```sh
    aws iam create-access-key --user-name eks-akane-developer | tee /tmp/eks-akane-developer.json
    ```

# AWS CLIのAssumeロールの設定

1.  `~/.aws/config` の設定

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    mkdir -p ~/.aws
    cat << EoF >> ~/.aws/config

    [profile eks-akane-developer]
    role_arn=arn:aws:iam::${ACCOUNT_ID}:role/akane-dev-eks-developer-role
    source_profile=eks-akane-developer
    EoF
    ```

1.  `~/.aws/credentials` の設定
    ※`アクセスキー`と`シークレットキー`を設定する。
    ※[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

    ```sh
    cat << EoF >> ~/.aws/credentials

    [eks-akane-developer]
    aws_access_key_id=$(jq -r .AccessKey.AccessKeyId /tmp/eks-akane-developer.json)
    aws_secret_access_key=$(jq -r .AccessKey.SecretAccessKey /tmp/eks-akane-developer.json)
    EoF
    ```

1.  Credentialsを切り替える

    ```sh
    export AWS_PROFILE=eks-akane-developer
    ```

1.  Credentialsの切り替えを確認する
    ※Arnに`assumed-role`と記載される。

    ```sh
    aws sts get-caller-identity
    ```

1.  コンテキストを切り替える
    ※クラスター名を設定します。

    ```sh
    aws eks update-kubeconfig --region ap-northeast-1 --name ${クラスタ名}
    ```

# developerの権限確認

1.  Namespace `akane` の認可確認
    ※`yes` と表示される。

    ```sh
    kubectl auth can-i create deploy -n akane
    kubectl auth can-i delete deploy -n akane
    ```

1.  Namespace `default` の認可確認
    ※`no` と表示される。

    ```sh
    kubectl auth can-i create deploy
    kubectl auth can-i delete deploy
    ```

# クリーンアップ
1.  Credentialsを切り替える
    ※`プロファイル名`を設定する。

    ```sh
    export AWS_PROFILE=${プロファイル名}
    ```

1.  aws-auth ConfigMap から削除する
    ※クラスター名を設定します。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    eksctl delete iamidentitymapping \
      --cluster ${クラスター名} \
      --arn arn:aws:iam::${ACCOUNT_ID}:role/akane-dev-eks-developer-role
    ```

1.  クラスターから削除する

    ```sh
    kubectl delete -f akane-developer-role-binding.yaml
    kubectl delete -f akane-developer-role.yaml
    kubectl delete -f akane-namespace.yaml
    ```

1.  IAMユーザーをIAMグループからデタッチする

    ```sh
    aws iam remove-user-from-group \
      --user-name eks-akane-developer \
      --group-name akane-dev-eks-developer-group
    ```

1.  IAMユーザーのアクセスキーを削除する

    ```sh
    aws iam delete-access-key \
      --user-name eks-akane-developer \
      --access-key-id "$(jq -r .AccessKey.AccessKeyId /tmp/eks-akane-developer.json)"
    ```

1.  IAMユーザーのアクセスキーのファイルを削除する

    ```sh
    rm -f /tmp/eks-akane-developer.json
    ```

1.  IAMユーザーを削除する

    ```sh
    aws iam delete-user --user-name eks-akane-developer
    ```

1.  IAMグループ用のポリシーをIAMグループからデタッチする

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    aws iam detach-group-policy \
      --group-name akane-dev-eks-developer-group \
      --policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-developer-group-policy"
    ```

1.  IAMグループ用のポリシーを削除する

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    aws iam delete-policy \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-developer-group-policy
    ```

1.  IAMグループを削除する
    ※今回はロール名を`akane-dev-eks-developer-group`にしています。

    ```sh
    aws iam delete-group --group-name akane-dev-eks-developer-group
    ```


1.  IAMロール用のポリシーをIAMロールからデタッチする

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    aws iam detach-role-policy \
      --role-name akane-dev-eks-developer-role \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-developer-role-policy
    ```

1.  IAMロール用のポリシーを削除する

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    aws iam delete-policy \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-developer-role-policy
    ```

1.  IAMロールを削除する

    ```sh
    aws iam delete-role \
      --role-name akane-dev-eks-developer-role
    ```



# 参考
[WHAT IS RBAC?](https://www.eksworkshop.com/beginner/090_rbac/intro/)
[Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
[クラスターへの IAM ユーザーおよびロールアクセスを有効にする](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html)
[Manage IAM users and roles](https://eksctl.io/usage/iam-identity-mappings/)
[Identity and Access Management](https://aws.github.io/aws-eks-best-practices/security/docs/iam/)