Amazon EKS IAM authentication: How to add an IAM user

Friday, Oct 26, 2018| Tags: eks, kubernetes, aws, authentication, iam

Note: This blog provides a deep dive on EKS authentication. If your goal is to be able to just add/delete eks users then follow this eksuser-amazon-eks-user-management-tool

When you create an EKS cluster it uses credentials of the user creating the cluster to set things up and assigns the user cluster-admin rights on the cluster through kubernetes RBAC.

EKS uses IAM for authentication. It uses aws-iam-authenticator for authentication using webhook token authentication of kubernetes. For authorization EKS uses kubernetes RBAC.

The flow looks like:

EKS Auth Flow

In this post we will learn how to add an IAM user to EKS for him/her to access kubernetes resources.

Let’s say there are 3 people:

EKS Users

  1. Prabhat - created the cluster. Hence has admin privileges on the cluster.
  2. Adam - the cluster admin that prabhat will add to EKS
  3. Dave - the developer that prabhat will add to EKS

The steps that we will follow are:

1. On Prabhat’s laptop in AWS account:

  1. Create an IAM policy that will be used the IAM users. (skip if you already have a policy with required rights. check details for additional info)
  2. Create an IAM user for Adam and Dave (skip if you already have the users)
  3. Attach policy to the IAM user (skip if existing setup already has rights)
  4. Generate aws AccessKeyId and SecretAccessKey for Adam and Dave

2. From Prabhat’s laptop on EKS cluster:

  1. Add the IAM users adam and dave to the cluster configmap aws-auth
  2. Create an admin EKS ClusterRole and a developer ClusterRole
  3. Create an EKS ClusterRoleBinding for both ClusterRoles

3. On the machine of the Adam and Dave IAM users who will access the EKS cluster:

  1. Set up AWS CLI by following the steps here
  2. Install kubectl
  3. Install aws-iam-authenticator
  4. Generate the kubeconfig file
  5. Access the cluster

Now let’s get into details.

1. On Prabhat’s laptop in AWS account:

  • 1. Create an IAM policy that will be used by the IAM users.

You don’t really need to create a new policy, but we will create a minimal policy that is required. Essentially we need the user to have 2 rights. eks:ListCluster, eks:DescribeCluster . These will be used to generate the kubeconfig for connecting to the cluster by Adam and Dave.

Now let’s create the policy.

$ aws iam create-policy --policy-name=eks-readonly --policy-document='{"Version": "2012-10-17", "Statement": {"Sid": "45345354354", "Effect": "Allow", "Action": ["eks:DescribeCluster", "eks:ListCluster" ], "Resource": "*" }}'
Output:

    {
    "Policy": {
        "PolicyName": "eks-readonly",
        "PolicyId": "ANPAID2WKUBOUCNJMOOL2",
        "Arn": "arn:aws:iam::012345678910:policy/eks-readonly",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "IsAttachable": true,
        "CreateDate": "2018-10-28T00:25:20Z",
        "UpdateDate": "2018-10-28T00:25:20Z"
        }
    }
  • 2. Create an IAM user for Adam and Dave
$ aws iam create-user --user-name=adam
$ aws iam create-user --user-name=dave
  • 3. Attach the IAM policy to both users
$ aws iam attach-user-policy --user-name=adam --policy-arn=arn:aws:iam::012345678910:policy/eks-readonly
$ aws iam attach-user-policy --user-name=dave --policy-arn=arn:aws:iam::012345678910:policy/eks-readonly
  • 4. Generate aws AccessKeyId and SecretAccessKey for Adam and Dave
$ aws iam create-access-key --user-name=adam
$ aws iam create-access-key --user-name=dave

Capture and keep the AccessKeyId and SecretAccessKey obtained in this step. You will need it when configuring machines oof Adam and Dave during AWS CLI configuration.

2. From Prabhat’s laptop on EKS cluster:

  • 1. Add the IAM users adam and dave to the cluster configmap aws-auth

First get the dump of existing aws auth configmap

$ kubectl -n kube-system get configmap aws-auth -o yaml > aws-auth.yaml

This would create a file with below contents:

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::012345678910:role/EKS-dev3-DefaultNodeGroup-NodeInstanceRole-1Q9T2ZHVLGCU1
      username: system:node:{{EC2PrivateDNSName}}
kind: ConfigMap
metadata:
  creationTimestamp: 2018-09-01T15:32:05Z
  name: aws-auth
  namespace: kube-system

Modify aws-auth.yaml to add dave and adam to mapUsers section:

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::012345678910:role/EKS-dev3-DefaultNodeGroup-NodeInstanceRole-1Q9T2ZHVLGCU1
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    - userarn: arn:aws:iam::012345678910:user/dave
      username: dave
    - userarn: arn:aws:iam::012345678910:user/adam
      username: adam
kind: ConfigMap
metadata:
  creationTimestamp: 2018-09-01T15:32:05Z
  name: aws-auth
  namespace: kube-system
$ kubectl -n kube-system apply -f aws-auth.yaml'
  • 2. Create an admin EKS ClusterRole and a developer ClusterRole

admin will have rights over all the resources.

create a file adminClusterRole.yaml

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: myadmin
rules:
- apiGroups: [ "*" ]
  resources: ["*"]
  verbs: ["*"]
- nonResourceURLs: ["*"]
  verbs: ["*"]

Run:

$ kubectl apply -f adminClusterRole.yaml

Developer will have rights only to the namespace “app1”. Since the rights of developer are only for a particular namespace we will create a Role instead of a ClusterRole.

create a file developerRole.yaml

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: mydeveloper
  namespace: app1
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]

Run:

$ kubectl apply -f developerRole.yaml

  • 3. Create an EKS ClusterRoleBinding and RoleBinding

adminClusterRoleBinding.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: myadmin
subjects:
- kind: User
  name: adam
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: myadmin
  apiGroup: rbac.authorization.k8s.io

Run:

$ kubectl apply -f adminClusterRoleBinding.yaml

Since developer access is restricted to a namespace app1 we will create a RoleBinding (as opposed to ClusterRoleBinding) developerRoleBinding.yaml

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: mydeveloper
  namespace: app1
subjects:
- kind: User
  name: dave
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: mydeveloper
  apiGroup: rbac.authorization.k8s.io

Run:

$ kubectl apply -f developerRoleBinding.yaml

3. On the machine of the Adam and Dave IAM users who will access the EKS cluster:

  • 1. Set up AWS CLI by following the steps here
  • 2. Install kubectl using instruction here
  • 3. Install aws-iam-authenticator using steps from EKS docs
  • 4. Generate the kubeconfig file
    $ aws eks update-kubeconfig --name=<cluster-name>

Follow the steps on machines of both Adam and Dave

We are all done here. Now let’s access the cluster

On Dave’s machine

Try following:

$ kubectl get pods

Output:

Error from server (Forbidden): pods is forbidden: User "dave" cannot list pods in the namespace "default"

Since Dave does not have access to default namespace the above command fails. Let’s check if the commands in namespace app1 succeeds.

$ kubectl get pods -n app1

Output:

NAME                       READY   STATUS    RESTARTS   AGE
mongodb-84b7c86ff5-jqz97   1/1     Running   0          6d
mysql-58d5cb6fd4-rznkd     1/1     Running   0          5d

Voila! This succeeds as expected. Congratulations Dave.

On Adam’s machine

$ kubectl get ns

Output:

NAME             STATUS   AGE
app1             Active   12d
default          Active   14d
grafana          Active   5d
istio-system     Active   13d
jaeger           Active   13d
kube-public      Active   14d
kube-system      Active   14d
metrics          Active   6d
openvpn          Active   12d
prometheus       Active   6d
spinnaker        Active   6d
test1            Active   14d

Congratulations. This works for Adam.

Adam can run many more commands in any namespace with success.

Bonus

Now the above steps are a bit too much just to add/delete users. I built an utility tool to make it easy to manage EKS users. It’s called eksuser. Head over to eksuser-amazon-eks-user-management-tool to find out, how it works.



Comments