AKS with AAD Pod Identity

Adding Pod Identity magic for granular access to Azure resources

The Azure AD Pod Identity allows you to configure access to cloud resources like DNS, Key Vault, ACR, or Blob Storage to Kubernetes pods.

Steps in Tutorial

This tutorial guide will run through the following steps:

  1. Enable and Install AAD Pod Identity (managed mode)
  2. Create a managed identity for Azure DNS access
  3. Create pod identity bindings for cert-manager and external-dns
  4. Install K8S addons: cert-manager, external-dns, ingress-nginx
  5. Deploy hello-kubernetes that uses an ingress

About Pod Identity Authorization

This guide will cover using managed mode, where the operator (you) will install the necessary AzureIdentity and AzureIdentityBinding resources, which is associated to a managed identity (that you will also create) to the desired target pod.

Requirements

For this guide, you will need an Azure subscription (see free).

Required tools

  • Kubernetes client tool (kubectl): command line tool that interacts with Kubernetes API
  • Helm (helm): command line tool for “templating and sharing Kubernetes manifests” (ref) that are bundled as Helm chart packages.
  • helm-diff plugin: allows you to see the changes made with helm or helmfile before applying the changes.
  • Helmfile (helmfile): command line tool that uses a “declarative specification for deploying Helm charts across many environments” (ref).

Optional tools

I highly recommend having a POSIX shell (sh) such as GNU Bash (bash) or Zsh (zsh). These scripts were tested on either of these shells on macOS and Ubuntu Linux.

Project Setup

The following file structure will be used:

~/azure_podid/
├── demos
│ └── hello-kubernetes
│ └── helmfile.yaml
├── env.sh
└── examples
└── cert-manager
├── helmfile.yaml
└── issuers.yaml

Project environment variables

Setup these environment variables

Azure components

Create Azure Resources: Azure DNS and AKS

You can provision Azure DNS and AKS with the following steps:

source env.sh
kubectl get all --all-namespaces

Enable and Install AAD Pod Identity

In order to use the automation for AAD Pod Identity, the preview feature must be enabled. This can be done with the following commands:

az aks update \
--resource-group ${AZ_RESOURCE_GROUP} \
--name ${AZ_CLUSTER_NAME} \
--enable-pod-identity
kubectl get all --namespace kube-system --selector component=nmi
kubectl get AzurePodIdentityException --namespace kube-system

Create a Managed Identity

Run the commands below to create a managed identity with a role assignment that permits upserts to the Azure DNS zone that was created earlier.

Kubernetes Components

Deploy Identity Bindings

Before installing the addons, the pod identity resources AzureIdentity and AzureIdentityBinding need to be configured to allow external-dns and cert-manager to access the Azure DNS zone.

kubectl get \
--namespace kube-addons \
AzureIdentity,AzureIdentityBinding

Kube Addons Helmfile

Copy the file below and save as examples/cert-manager/helmfile.yaml:

Cert Manager Issuers Helmfile

Copy the file below and save as examples/cert-manager/issuers.yaml:

Deploy addons and issuers

When ready, run the following commands to deploy cert-manager, external-dns, and ingress-nginx:

kubectl get all --namespace kube-addons
kubectl get --namespace kube-addons ClusterIssuer

Demo Application: hello-kubernetes

Copy the file below and save as demos/hello-kubernetes/helmfile.yaml:

Select the Certificate Issuer

You will need to choose which issuer by setting the ACME_ISSUER environment variable. If you are using a public domain that can be verified, use the letsencrypt-prod. If you are using a private domain or want to test out the solution first, use letsencrypt-staging.

Deploy hello-kubernetes

When ready, run these commands (this assumes domain is a public domain):

source env.shexport ACME_ISSUER=letsencrypt-prod
helmfile --file demos/hello-kubernetes/helmfile.yaml
kubectl get all,ing,certificate --namespace hello

Verify hello-kubernetes

Point the browser the address using your domain, such as https://hello.example.com. This should land on one of the three pods:

Cleanup

The AKS cluster and subsequent resources, including persistent volumes, can be deleted with the following command:

az aks delete \
--resource-group ${AZ_RESOURCE_GROUP} \
--name ${AZ_CLUSTER_NAME}
az network dns zone delete \
--resource-group ${AZ_RESOURCE_GROUP} \
--name ${AZ_DNS_DOMAIN}

Resources

These are some resources I have come across when researching this article.

Blog Source Code

The blog source code contains more robust versions of these scripts that verify env vars.

Azure AD Pod Identity

External DNS

Cert Manager

NGINX Ingress Controller

Related Articles

This articles delve further into the underlying technologies and concepts behind them.

Conclusion

The major take away for this article are how to enable, install, and use AAD Pod Identity with AKS.

Linux NinjaPants Automation Engineering Mutant — exploring DevOps, o11y, k8s, progressive deployment (ci/cd), cloud native infra, infra as code