À la fin de ce tutoriel, vous activerez OIDC issuer + Workload Identity sur un cluster AKS, créerez une User-Assigned Managed Identity (UAMI), lierez un ServiceAccount via federated credential, et prouverez l’accès à un Key Vault lab — sans secret Service Principal dans Git ni pod Identity legacy — le tout en
canadacentral(data residency Canada, équivalent AWSca-central-1).Niveau : Intermédiaire · Temps estimé : 55–75 min · Versions cibles : AKS 1.29+ · Microsoft Entra Workload ID · Azure CLI 2.60+ · kubectl · Dernière vérification : 2026-09-11 · Region :
canadacentralSlug :
wow-azure-workload-identity· Série : WOW Platform / DevOps · Mot-clé SEO : Azure Workload Identity AKS← Connexe : Service connections OIDC · Entra ID bases · Secrets K8s · GitHub Actions OIDC AWS · Pipelines + Key Vault · Hub : Azure DevOps · Kubernetes
Prérequis
- Subscription Azure lab avec droits Contributor (ou Owner) sur un Resource Group jetable
- Cluster AKS lab (création ci-dessous) ou cluster existant à mettre à jour ;
azCLI etkubectlconfigurés - Notions Microsoft Entra ID / managed identity (Entra ID bases) et ServiceAccount Kubernetes (Secrets K8s)
- Budget d’alerte Azure activé — AKS + Key Vault coûtent si oubliés ; suppression obligatoire en fin de session
- Aucun secret réel dans Git : placeholders
lab-*uniquement
export RESOURCE_GROUP=rg-lab-wi-aks
export LOCATION=canadacentral
export CLUSTER_NAME=aks-lab-wi
export IDENTITY_NAME=uami-lab-wi
export NAMESPACE=wi-demo
export SERVICE_ACCOUNT_NAME=sa-wi-demo
# Suffixe unique pour Key Vault (nom globalement unique)
export KEYVAULT_NAME=kv-lab-wi$(openssl rand -hex 3)
az account show --query "{name:name,id:id,tenantId:tenantId}" -o table
az group create -n "$RESOURCE_GROUP" -l "$LOCATION"
Vérifiez le tenant lab — jamais un compte de production. Région canadacentral aligne la résidence des données Canada (équivalent AWS ca-central-1).
Ce que nous allons construire
Lab Azure Workload Identity AKS (canadacentral)
├── AKS OIDC issuer + workload-identity enabled
├── UAMI (User-Assigned Managed Identity)
├── Key Vault lab + role Key Vault Secrets User
├── Federated credential (SA → UAMI)
├── ServiceAccount annoté + Pod labelé
├── Preuve : az login --federated-token → secret show
└── Nettoyage : pod → FIC → KV → UAMI → AKS → RG
(Schéma — alt : « Pod AKS échange un token OIDC contre un accès Key Vault via Entra Workload Identity ».)
Objectif plateforme : les workloads Kubernetes n’embarquent plus de client secret SP ; l’identité est fédérée (comme IRSA/EKS côté AWS). GitOps versionne SA + annotations, pas les secrets longs. Wow : un kubectl apply + un FIC Entra suffisent pour lire un secret KV — zéro rotation manuelle de clé SP.
Étape 1 — Pourquoi Workload Identity (vs secrets SP / aad-pod-identity)
Microsoft Entra Workload ID remplace le secret SP dans un Secret K8s et l’ancien aad-pod-identity (déprécié). Le pod reçoit un token projeté ; Entra l’échange contre un access token.
| Approche | Forces | Limites |
|---|---|---|
| Secret SP dans K8s | Simple | Rotation, fuite Git |
| aad-pod-identity | Identité pod | Déprécié (NMI/MIC) |
| Workload Identity | OIDC natif ; FIC/SA ; DefaultAzureCredential | OIDC+WI requis |
Même pattern que OIDC Azure DevOps et GitHub → AWS OIDC : federation, zero secret long dans le repo.
Étape 2 — Créer ou activer AKS (OIDC + Workload Identity)
Création lab (1 nœud — adaptez le SKU) ou update d’un cluster existant :
# Create
az aks create -g "$RESOURCE_GROUP" -n "$CLUSTER_NAME" -l "$LOCATION"
--node-count 1 --generate-ssh-keys
--enable-oidc-issuer --enable-workload-identity
--tags Environment=lab ManagedBy=wow-wi Project=devops-elastic-hayway
# Ou update
az aks update -g "$RESOURCE_GROUP" -n "$CLUSTER_NAME"
--enable-oidc-issuer --enable-workload-identity
az aks get-credentials -g "$RESOURCE_GROUP" -n "$CLUSTER_NAME" --overwrite-existing
kubectl get nodes
Attendu : nœuds Ready. Sans OIDC issuer, la fédération Entra échoue.
Étape 3 — Récupérer l’OIDC issuer URL
export AKS_OIDC_ISSUER="$(az aks show -g "$RESOURCE_GROUP" -n "$CLUSTER_NAME"
--query "oidcIssuerProfile.issuerUrl" -o tsv)"
echo "AKS_OIDC_ISSUER=$AKS_OIDC_ISSUER"
Cette URL est l’issuer du federated credential.
Étape 4 — User-Assigned Managed Identity (UAMI)
az identity create -g "$RESOURCE_GROUP" -n "$IDENTITY_NAME" -l "$LOCATION"
export USER_ASSIGNED_CLIENT_ID="$(az identity show -g "$RESOURCE_GROUP" -n "$IDENTITY_NAME" --query clientId -o tsv)"
export USER_ASSIGNED_OBJECT_ID="$(az identity show -g "$RESOURCE_GROUP" -n "$IDENTITY_NAME" --query principalId -o tsv)"
echo "CLIENT_ID=$USER_ASSIGNED_CLIENT_ID"
L’UAMI est l’identité Azure empruntée via OIDC — aucun secret à stocker.
Étape 5 — Key Vault lab + role Key Vault Secrets User
KV minimal + secret démo (placeholder) ; RBAC peut prendre 1–2 min :
az keyvault create -g "$RESOURCE_GROUP" -n "$KEYVAULT_NAME" -l "$LOCATION"
--enable-rbac-authorization true --sku standard
KV_ID="$(az keyvault show -n "$KEYVAULT_NAME" -g "$RESOURCE_GROUP" --query id -o tsv)"
az role assignment create --role "Key Vault Secrets Officer"
--assignee "$(az ad signed-in-user show --query id -o tsv)" --scope "$KV_ID"
az keyvault secret set --vault-name "$KEYVAULT_NAME"
--name "lab-demo-secret" --value "REPLACE_ME_LAB_ONLY"
az role assignment create --role "Key Vault Secrets User"
--assignee-object-id "$USER_ASSIGNED_OBJECT_ID"
--assignee-principal-type ServicePrincipal --scope "$KV_ID"
Least privilege : Key Vault Secrets User sur le scope KV — pas Contributor subscription.
Étape 6 — ServiceAccount annoté
kubectl create namespace "$NAMESPACE"
cat <<YAML | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: ${SERVICE_ACCOUNT_NAME}
namespace: ${NAMESPACE}
annotations:
azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"
labels:
azure.workload.identity/use: "true"
YAML
L’annotation lie le SA à l’UAMI. Le pod doit aussi porter le label use.
Étape 7 — Federated credential (FIC)
Subject exact system:serviceaccount:NAMESPACE:SA ; audience Entra :
az identity federated-credential create
--name fic-aks-wi-demo --identity-name "$IDENTITY_NAME"
--resource-group "$RESOURCE_GROUP" --issuer "$AKS_OIDC_ISSUER"
--subject "system:serviceaccount:${NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
--audiences "api://AzureADTokenExchange"
Prod : un FIC par SA (pas de wildcard), namespaces séparés.
Étape 8 — Déployer le pod et vérifier les variables
# pod-wi-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: wi-demo
namespace: wi-demo
labels:
azure.workload.identity/use: "true"
app.kubernetes.io/part-of: wow-azure-workload-identity
spec:
serviceAccountName: sa-wi-demo
containers:
- name: azure-cli
image: mcr.microsoft.com/azure-cli:2.64.0
command: ["sleep", "3600"]
kubectl apply -f pod-wi-demo.yaml
kubectl -n "$NAMESPACE" wait --for=condition=Ready pod/wi-demo --timeout=120s
kubectl -n "$NAMESPACE" exec wi-demo -- env | grep -E 'AZURE_CLIENT_ID|AZURE_TENANT_ID|AZURE_FEDERATED_TOKEN_FILE'
Attendu : AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_FEDERATED_TOKEN_FILE. Sans le label use sur le pod, ces variables manquent. Tip : kubectl -n wi-demo describe pod wi-demo doit montrer le volume projeté du token fédéré.
Étape 9 — Preuve d’accès Key Vault
Dans le pod :
kubectl -n "$NAMESPACE" exec -it wi-demo -- bash -lc '
set -euo pipefail
az login --service-principal
-u "$AZURE_CLIENT_ID"
--tenant "$AZURE_TENANT_ID"
--federated-token "$(cat "$AZURE_FEDERATED_TOKEN_FILE")"
az keyvault secret show
--vault-name "'"$KEYVAULT_NAME"'"
--name lab-demo-secret
--query "{name:name,enabled:attributes.enabled}" -o table
'
En app réelle, DefaultAzureCredential (Python/.NET/Go) lit ces variables — pas de az login :
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
client = SecretClient(
vault_url="https://kv-lab-wiXXXX.vault.azure.net/",
credential=DefaultAzureCredential(),
)
print(client.get_secret("lab-demo-secret").name)
Étape 10 — Notes prod (platform 2026)
- Least privilege au scope minimal (KV, ACR pull) — jamais Owner
- Un FIC par SA ; pin images (
azure-cli:2.64.0) ; pas de secrets longs dans Git - Policy (Azure Policy / Gatekeeper) pour forcer le label WI
- CI : service connections OIDC, variables + Key Vault
Nettoyage (obligatoire)
Ordre : pod → ns → FIC → KV → UAMI → AKS → RG.
kubectl -n "$NAMESPACE" delete pod wi-demo --ignore-not-found
kubectl delete namespace "$NAMESPACE" --ignore-not-found
az identity federated-credential delete --identity-name "$IDENTITY_NAME"
-g "$RESOURCE_GROUP" --name fic-aks-wi-demo --yes 2>/dev/null || true
az keyvault delete -n "$KEYVAULT_NAME" -g "$RESOURCE_GROUP" || true
az keyvault purge -n "$KEYVAULT_NAME" -l "$LOCATION" 2>/dev/null || true
az identity delete -g "$RESOURCE_GROUP" -n "$IDENTITY_NAME" || true
az aks delete -g "$RESOURCE_GROUP" -n "$CLUSTER_NAME" --yes --no-wait
# az group delete -n "$RESOURCE_GROUP" --yes --no-wait
Vérifiez qu’aucun AKS / KV soft-deleted ne reste en canadacentral.
Coûts du lab
| Ressource | Ordre de grandeur |
|---|---|
| AKS + 1 nœud | Quelques USD/h selon SKU — delete vite |
| UAMI / FIC | Gratuit |
| Key Vault lab | Cents / jour |
Alerte budget Azure ; jamais d’AKS overnight oublié.
Erreurs fréquentes
| Symptôme | Cause | Correction |
|---|---|---|
Pas de AZURE_* dans le pod |
Label use manquant / webhook off |
Label sur le pod ; WI enabled sur AKS |
| AADSTS70021 / invalid subject | Subject FIC ≠ SA réel | Recréer FIC : system:serviceaccount:ns:sa |
| Forbidden Key Vault | RBAC pas propagé / mauvais rôle | Attendre ; Key Vault Secrets User sur scope KV |
| OIDC issuer vide | Feature non activée | az aks update --enable-oidc-issuer |
| aad-pod-identity encore installé | Legacy en conflit | Désinstaller NMI/MIC ; migrer vers WI |
| Token file vide / expiré | Projection WI absente | Relancer le pod ; vérifier webhook WI Running |
FAQ
Workload Identity remplace-t-il les secrets K8s ?
Pour l’auth Azure, oui (plus de client secret SP). Les secrets applicatifs restent à part (K8s Secrets, Key Vault).
aad-pod-identity est-il encore supporté ?
Non pour les designs 2026 — migrez vers Entra Workload ID.
Faut-il un cluster neuf ?
Non. az aks update --enable-oidc-issuer --enable-workload-identity suffit.
Différence avec OIDC ADO / GitHub ?
Même federation ; ici l’issuer est l’URL OIDC AKS.
Pourquoi canadacentral ?
Data residency Canada, parité labs AWS ca-central-1. RG, AKS, UAMI, KV dans la même région.
Un FIC pour plusieurs SA ?
Non. Un subject = un SA ; partager élargit le blast radius.
Quiz (3 questions)
1. Quel flag AKS active l’émetteur de tokens pour la fédération Entra ?
– A. --enable-addons monitoring uniquement
– B. --enable-oidc-issuer (avec --enable-workload-identity)
– C. --enable-cluster-autoscaler
2. Quel subject utiliser dans le federated credential ?
– A. Le nom du Deployment
– B. system:serviceaccount:NAMESPACE:SERVICE_ACCOUNT
– C. L’Object ID de l’UAMI
3. Pourquoi le label azure.workload.identity/use: "true" sur le pod ?
– A. Pour facturer Azure
– B. Pour que le webhook injecte AZURE_CLIENT_ID / token file
– C. Pour remplacer kube-proxy
Réponses : 1‑B · 2‑B · 3‑B
Pour aller plus loin
- DefaultAzureCredential dans vos images app
- CI OIDC : service connections, GitHub Actions OIDC AWS
- Variables + Key Vault · GitOps SA+FIC (série WOW)
Maillage WOW / Platform
| Série | WOW ×50 — Platform Engineering & GitOps |
| Voisins | wow-crossplane-aws · wow-platform-engineering-2026 · wow-backstage-idp · wow-argo-cd-gitops |
| Hubs live | Azure · Kubernetes · Azure DevOps (menus du site) |
Meta publication (SEO) — Publish HOLD
- Title SEO : Azure Workload Identity sur AKS : lab sans secrets SP (2026)
- Meta description (≤ 160) : Activez OIDC et Workload Identity sur AKS en canadacentral, liez une UAMI à un ServiceAccount et lisez un secret Key Vault sans client secret.
- Image mise en avant :
assets/web/devopelastichayway/cover-wow-azure-workload-identity-1200x630.webp - Cover alt : Pod AKS authentifié à Key Vault via Entra Workload Identity
- Catégorie : DevOps / Platform · Niveau : Intermédiaire
- KW principal : Azure Workload Identity AKS · Secondaires : Entra Workload ID, federated credential AKS, UAMI ServiceAccount, Key Vault Secrets User, aad-pod-identity déprécié
- Schema : HowTo + FAQPage + Article
- URL cible : https://devopelastichayway.com/tutoriels/wow-azure-workload-identity/
- Statut : Publish HOLD — draft only, pas de Rank Math live sans feu vert
- Region lab :
canadacentral(Canada Central ; équivalent AWSca-central-1)
Pour aller plus loin — hubs live
Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.