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

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

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

# 実行環境の準備
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-admin-role`にしています。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    ADMIN_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-admin-role \
      --assume-role-policy-document "${ADMIN_ASSUME_ROLE_POLICY}"
    ```

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

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    ADMIN_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-admin-role-policy \
        --policy-document "${ADMIN_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-admin-role \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-admin-role-policy
    ```

# IAMグループの作成

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

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

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

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    ADMIN_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-admin-role"
        }
      ]
    }')
    aws iam create-policy \
        --policy-name akane-dev-eks-admin-group-policy \
        --policy-document "${ADMIN_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-admin-group \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-admin-group-policy
    ```

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

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-admin-role \
      --username dev-akane-admin-user \
      --group system:masters
    ```

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

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

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

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

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

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

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

    ```sh
    aws iam create-access-key --user-name eks-akane-admin | tee /tmp/eks-akane-admin.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-admin]
    role_arn=arn:aws:iam::${ACCOUNT_ID}:role/akane-dev-eks-admin-role
    source_profile=eks-akane-admin
    EoF
    ```

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

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

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

1.  Credentialsを切り替える

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

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

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

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

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

# adminの権限確認

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

    ```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-admin-role
    ```

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

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

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

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

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

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

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

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

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-admin-group \
      --policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-admin-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-admin-group-policy
    ```

1.  IAMグループを削除する

    ```sh
    aws iam delete-group --group-name akane-dev-eks-admin-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-admin-role \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-eks-admin-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-admin-role-policy
    ```

1.  IAMロールを削除する

    ```sh
    aws iam delete-role \
      --role-name akane-dev-eks-admin-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/)