Playing with AKS & AAD

Houssem Dellai
FAUN — Developer Community 🐾
6 min readMar 2, 2019

--

This quick workshop will walk you through configuring AKS with AAD to use RBAC to authenticate users.

Introduction

The development team members needs to access Kubernetes cluster to deploy apps and configure the cluster. But, not all members needs the same level of access rights. It is even a best practice or a must have to grant members different access levels. For example, developers can get, create and delete deployments inside their own namespace. And, Ops guys can configure the cluster to add or remove users, scale the cluster or upgrade it. This will secure the k8s cluster and reduce the risk of bad manipulations.

You will need an Azure subscription, az and kubectl cli installed.

This workshop will start by creating Azure AD client and server apps. Then we’ll create an AKS cluster configured with AAD. And we’ll finish by creating the Role and RoleBinding k8s manifest files.

1. Create Azure AD server and client apps

We need to create a server and client apps, those will be used to authenticate the users connecting to AKS through AAD. This means the user should be first created in AAD to have access to the cluster. This is the authentication part. For the authorisation part, it will be managed by Role and RoleBinding k8s objects in section 3.

Please follow the steps described in the link here (just before section Create Cluster) to create client and server apps: https://docs.microsoft.com/en-us/azure/aks/aad-integration

At the end, we should have the AAD tenant Id, client app Id, server app Id and server app secret. We’ll use those to configure AKS with AAD.

2. Create AKS cluster configured with Azure Active Directory

Azure uses Resource Group to group resources related to the same application or service. All resources in Azure must live inside a resource group, including AKS. Let’s start by creating a resource group using the az command line.

$ az group create -name aks-aad-rg -location westeurope

If you have multiple Azure subscriptions, you can set a default one so that az commands points always to it, by using:

az account set “Your_Azure_Subscription_Id_Or_Name”

Then we can create the AKS cluster. Kubernetes uses OpenId Connect (OIDC) to authenticate users. And, AKS could be configured to use AAD as an implementation of OIDC. The az cli tool provide the options to make this configuration during (but not after) the creation of the cluster. Make sure to replace the values from your AAD. This will take about 5 minutes to run.

$ az aks create 
-resource-group
aks-aad-rg \
-name
aks-aad \
-generate-ssh-keys
\
-aad-server-app-id
cbb2efcb-9b3c-4441-b58f-9c6cca37 \
-aad-server-app-secret
VBnbw1gEhxtRVfKTv8dYD+MyraLF5jn= \
-aad-client-app-id
4c2a05a5–7ed1–4a2c-b4aa-b78bc \
-aad-tenant-id
72f988bf-0000–0000–0000–2d7cd011db47

Now, all users from the AAD account can authenticate to the AKS cluster. But, they can not do any operation as they don’t have yet any permission to do whatever. We need to grant them access to k8s resources through Role and RoleBinding. Before that, we need to access the cluster as admin, in order to assign the roles.

3. Connect to AKS cluster

We need to connect to AKS in order to run kubectl commands against the new cluster, as an admin.

$ az aks get-credentials \
-resource-group
aks-aad-rg \
-name
aks-aad
--admin
Merged "aks-aad-admin" as current context in /Users/houssem/.kube/config

By the way, the source code for all the commands are here: github.com/HoussemDellai/rbac-aks-aad

And this workshop is available as a video.

Video: RBAC with AKS & Azure AD

4. Create the Role and RoleBinding

Let’s create the Role which will define access to certain resources. For example, only reading information from pods.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace:
default
name: pod-reader
rules:
- apiGroups:
[“”] # “” indicates the core API group
resources: [“pods”]
verbs: [“get”, “watch”, “list”]

To assign the role to a user, we need to use RoleBinding.

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name:
read-pods
namespace: default
subjects:
- kind:
User
name: "houssem.dellai@live.com" # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind:
Role #this must be Role or ClusterRole
name: pod-reader # must match the name of the Role
apiGroup: rbac.authorization.k8s.io

We can use a Group instead of User, to bind to all users within the AAD group.

Then we deploy both files using kubectl:

$ kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/pod-reader created
$ kubectl apply -f role-binding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created

We can check if the Role and RoleBinding were successfully created:

$ kubectl get roles
NAME AGE
pod-reader 2m
$ kubectl get rolebindings
NAME AGE
read-pods 2m

5. Test authentication and authorisation to AKS

Now that everything is configured, we will pretend to be the user used in RoleBinding. We’ll connect to the AKS cluster from another machine. This is using login to Azure, not to to the cluster.

$ az aks get-credentials \
-resource-group
aks-aad-rg \
-name
aks-aad
Merged "aks-aad" as current context in /Users/houssem/.kube/config

Then we’ll try the allowed command:

$ kubectl get pods
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code CL7DWV3P2 to authenticate.

Because we added authentication, it is asking to login to the cluster. We’ll login as the user specified in RoleBinding. We need to launch the browser in the specified url address and use the given code.

Then we press continue.

Make sure the user used in RoleBinding exists also in the Azure AD.

And here we come to the most exciting part, the login to the AKS cluster!

We can login with the email and password for the user.

This web page means that you are logged in successfully !

We run again the allowed command:

$ kubectl get pods
No resources found. # we didn't created a Pod yet !

If we try to run one of the non allowed operations, then it will fail!

$ kubectl get deployments
Error from server (Forbidden): deployments.extensions is forbidden: User “f97fc9ba-ebda-439e-825a-..” cannot list deployments.extensions in the namespace “default”

If we try to get the pods from all the namespaces, that will also fail. Because we configured the user in Role to get pods from only the default namespace.

$ kubectl get pods --all-namespaces
Error from server (Forbidden): pods is forbidden: User "f97fc9ba-ebda-439e-825a-0e25801cb32c" cannot list pods at the cluster scope

Conclusion

We have configured a user to login and get access to specific AKS resources. We could also do this for an entire AAD group.

To learn more about Kubernetes:

Video series: Kubernetes with Azure and Azure DevOps

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--

Premier Field Engineer at Microsoft, ex MVP, Cloud & DevOps enthusiast. I share what I learn in my professional experience through articles and videos.