Stepan's technical notes

Notes about my journey to the Cloud

11 Dec 2019

AWS EKS basics: read-only cluster role

Sometimes you are searching for an easy solution but you must go through dozens of pages of documentation instead. This blog post is going to describe one particular topic in short: how to configure read-only role with aws-iam-authenticator.

EKS contains aws-iam-authenticator by default, hence we need to focus on configuration of Kubernetes RBAC and AWS IAM only.

AWS IAM configuration

As we are creating a read-only role, we can create role EKSReadOnly, this is the trust relationship document which allows us to assume this role from any account or role in the account 123456789123:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789123:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

In the real-life scenario, I suggest more restrictive rules for the trust realationship. Also, you can put in place some restrictions even on the other side and control which users, groups or roles can assign this particular role.

We also need to configure some minimal permission so the role will be able to obtain kubeconfig from the EKS cluster:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "eks:DescribeCluster",
                "eks:ListClusters"
            ],
            "Resource": "*"
        }
    ]
}

Now we can assign these permissions to the EKSReadOnly role and then we can continue with the Kubernetes part of this setup.

aws-iam-authenticator and RBAC configuration

First of all, let’s create a simple ClusterRole and ClusterRoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
  name: read-only
  namespace: default
rules:
- apiGroups:
  - ""
  resources: ["*"]
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - extensions
  resources: ["*"]
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - apps
  resources: ["*"]
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-only
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: read-only
subjects:
- kind: Group
  name: read-only

Nothing really special happens there, as those resources are not scoped to the namespaces, we can just apply them with kubectl apply without any special care and then we can proceed to the configuration of aws-iam-authenticator. Please note the Group name at the endof the manifest. We’ll need it shortly.

Configuration of IAM authenticator lives in the ConfigMap aws-auth that is located in the kube-system namespace.

The desired configuration for the read-only ClusterRole will look like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: arn:aws:iam::123456789123:role/KubernetesNode
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
    - rolearn: arn:aws:iam::123456789123:role/EKSReadOnly
      username: ro
      groups:
        - read-only

In this configuration, we are just saying that anyone who’s using EKSReadOnly IAM role will be mapped to Kubernetes user ro in group read-only.

And that’s exactly what we need. Now we can just play with IAM resources so we can build some mechanism for the assignment of similar roles.

Wrap

In this short post, I’ve just put together pieces of the documentation I’ve found all around the internet. The main purpose was to create a specific tutorial with something different than system:masters built-in group.

Please note this example is not 100% secure and you should really pay an extra attention when implementing something similar in your environment.

Do you have any interesting EKS topics I can cover in blog posts? Do not hesitate to suggest such a topic in the comments. This might be a really great series of simple tutorials!

comments powered by Disqus