Proposed Pull Request Change

title description ms.topic ms.subservice ms.service ms.custom ms.date author ms.author
Migrate Azure Kubernetes Service (AKS) Pods to Microsoft Entra Workload ID Migrate AKS pods from pod-managed identities to Microsoft Entra Workload ID using Azure Identity SDK versions or migration sidecar approaches. how-to aks-security azure-kubernetes-service devx-track-azurecli, innovation-engine 07/31/2023 davidsmatlak davidsmatlak
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: Migrate Azure Kubernetes Service (AKS) Pods to Microsoft Entra Workload ID description: Migrate AKS pods from pod-managed identities to Microsoft Entra Workload ID using Azure Identity SDK versions or migration sidecar approaches. ms.topic: how-to ms.subservice: aks-security ms.service: azure-kubernetes-service ms.custom: devx-track-azurecli, innovation-engine ms.date: 07/31/2023 author: davidsmatlak ms.author: davidsmatlak # Customer intent: "As a Kubernetes administrator, I want to migrate my AKS pods from pod-managed identities to workload identity, so that I can enhance security and streamline authentication for my containerized applications." --- # Migrate Azure Kubernetes Service (AKS) pods from pod-managed identity to Microsoft Entra Workload ID [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://go.microsoft.com/fwlink/?linkid=2303216) Migrate AKS pods from pod-managed identities to [Microsoft Entra Workload ID][workload-identity-overview] (workload identity) using one of three approaches based on your current [Azure Identity SDK][azure-identity-libraries] version: latest SDK parallel deployment, migration sidecar proxy (Linux only), or SDK rewrite. ## Prerequisites - Azure CLI version 2.47.0 or later. Run the `az --version` command to find the version. If you need to install or upgrade, see [Install Azure CLI][install-azure-cli]. ## Set environment variables The following table lists the environment variables used in the commands throughout this article. Make sure to replace the placeholder values with your own values. | Environment variable | Description | Example value | | -------------------- | ----------- | ------------- | | `SUBSCRIPTION_ID` | The ID of the Azure subscription where the AKS cluster and managed identity are created. | `00000000-0000-0000-0000-000000000000` | | `RESOURCE_GROUP` | The name of the resource group where the AKS cluster and managed identity are created. | `myResourceGroup` | | `LOCATION` | The Azure region where the AKS cluster and managed identity are created. | `eastus` | | `CLUSTER_NAME` | The name of the AKS cluster. | `myAKSCluster` | | `MANAGED_IDENTITY_NAME` | The name of the user-assigned managed identity. | `myManagedIdentity` | | `SERVICE_ACCOUNT_NAME` | The name of the Kubernetes service account to create or associate with the managed identity. | `workload-identity-sa` | | `SERVICE_ACCOUNT_NAMESPACE` | The namespace of the Kubernetes service account. | `default` | | `FEDERATED_IDENTITY_NAME` | The name of the federated identity credential to create. | `myFederatedIdentity` | ## Choose a migration path Select the appropriate migration approach based on your current Azure Identity SDK version: - **Latest Azure Identity SDK**: If your application already uses the latest version of Azure Identity SDK, you can migrate by deploying Microsoft Entra Workload ID in parallel with existing pod-managed identity. - **Older SDK with migration sidecar** - If your application uses an older SDK version and runs on Linux containers, you can use a temporary migration sidecar to proxy Instance Metadata Service (IMDS) transactions while planning your SDK upgrade. - **Older SDK rewrite approach**: If your application uses an older SDK version, you can update your application code to use the latest Azure Identity SDK, then migrate to workload identity. ## Prepare for migration For all migration paths, you need to have the federated trust set up before you update your application to use Microsoft Entra Workload ID. The following are the minimum steps required: - [Create a managed identity](#create-a-managed-identity) credential. - Associate the user-assigned managed identity with the Kubernetes service account already used for the pod-managed identity or [create a new Kubernetes service account](#create-kubernetes-service-account) and then associate it with the managed identity. - [Establish a federated trust relationship](#establish-federated-identity-credential-trust) between the managed identity and Microsoft Entra ID using the [OpenID Connect (OIDC)][openid-connect-overview] issuer URL and the service account. ## Migrate from latest version of Azure Identity SDK **This migration path applies when** your application already uses the latest version of the Azure Identity SDK and you want to migrate with minimal code changes. **Migration approach**: Deploy Microsoft Entra Workload ID in parallel with pod-managed identity, verify functionality, then remove pod-managed identity. **Steps**: 1. Deploy Microsoft Entra Workload ID in parallel with existing pod-managed identity. 1. Restart your application deployment to begin using Microsoft Entra Workload ID (OIDC annotations are injected automatically). 1. Verify the application can authenticate successfully using workload identity. 1. [Remove the pod-managed identity](#remove-pod-managed-identity) annotations from your application. 1. Remove the pod-managed identity add-on from your cluster. ## Use a migration sidecar (Linux containers only) **This migration path applies when** your application uses an older version of the Azure Identity SDK, runs on Linux containers, and you need a temporary solution while planning SDK updates. **Migration approach**: Deploy a migration sidecar that proxies IMDS transactions to OIDC, allowing your existing application code to work without immediate changes. **Important limitations**: - **Linux containers only**. Windows containers aren't supported. - **Temporary solution** that's not intended for long-term production use. - **Planning required** to schedule SDK updates for long-term support. **Steps**: 1. [Deploy the workload with migration sidecar](#deploy-the-workload-with-migration-sidecar) to proxy IMDS transactions. 1. Verify authentication transactions complete successfully. 1. Schedule application SDK updates to supported Azure Identity versions. 1. Once SDKs are updated, remove the proxy sidecar and redeploy applications. ## Rewrite application for latest Azure Identity SDK **This migration path applies when** your application uses an older version of the Azure Identity SDK and you want to update to the latest supported SDK before migrating. **Migration approach**: Update your application code to use the latest Azure Identity SDK, then migrate to Microsoft Entra Workload ID with the updated code. **Technical outcomes**: - Uses current Azure Identity SDK versions (no deprecation timeline). - Supports both Linux and Windows containers (unlike sidecar approach). - Eliminates proxy components and IMDS translation overhead. **Steps**: 1. Update your application code to use the latest [Azure Identity SDK][azure-identity-supported-versions]. 2. Test the updated application with pod-managed identity. 3. Restart your application deployment to begin authenticating using Microsoft Entra Workload ID (OIDC annotations are injected automatically). 4. Verify authentication transactions complete successfully. 5. [Remove the pod-managed identity](#remove-pod-managed-identity) annotations and add-on. ## Set an active Azure subscription - Set a specific Azure subscription as the current active subscription using the [`az account set`][az-account-set] command. ```azurecli-interactive az account set --subscription $SUBSCRIPTION_ID ``` ## Create a managed identity - Create a managed identity using the [`az identity create`][az-identity-create] command. ```azurecli-interactive az identity create --name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP --location $LOCATION --subscription $SUBSCRIPTION_ID ``` ## Get managed identity client ID - Get the client ID of the managed identity and save it to an environmental variable using the [`az identity show`][az-identity-show] command. ```azurecli-interactive export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group $RESOURCE_GROUP --name $MANAGED_IDENTITY_NAME --query 'clientId' -otsv)" ``` ## Grant managed identity access to Azure resources - Grant the managed identity the permissions needed to access the required Azure resources. Follow the steps in [Assign a managed identity access to a resource][assign-rbac-managed-identity] to assign the appropriate role to the managed identity. ## Get OIDC issuer URL - Get the OIDC issuer URL and save it to an environmental variable using the [`az aks show`][az-aks-show] command. ```azurecli-interactive export AKS_OIDC_ISSUER="$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -o tsv)" ``` The variable should contain an issuer URL similar to the following example: ```output https://eastus.oic.prod-aks.azure.com/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000/ ``` By default, the issuer uses the base URL `https://{region}.oic.prod-aks.azure.com/{uuid}`, where the value for `{region}` matches the location the AKS cluster is deployed in. The value `{uuid}` represents the OIDC key. ## Get AKS cluster credentials - Get the AKS cluster credentials using the [`az aks get-credentials`][az-aks-get-credentials] command. ```azurecli-interactive az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP ``` ## Create Kubernetes service account - Create a Kubernetes service account and annotate it with the managed identity client ID using the `kubectl apply` command. Make sure to replace the placeholder values with your own values. ```bash cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: ${USER_ASSIGNED_CLIENT_ID} name: ${SERVICE_ACCOUNT_NAME} namespace: ${SERVICE_ACCOUNT_NAMESPACE} EOF ``` The following output resembles successful creation of the identity: ```output Serviceaccount/workload-identity-sa created ``` ## Establish federated identity credential trust - Create the federated identity credential between the managed identity, service account issuer, and subject using the [`az identity federated-credential create`][az-identity-federated-credential-create] command. ```azurecli-interactive az identity federated-credential create --name $FEDERATED_IDENTITY_NAME --identity-name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME} --audience api://AzureADTokenExchange ``` The federated identity credential takes a few minutes to propagate after being added. If a token request is made immediately after adding the federated identity credential, the token request might fail because the Azure AD directory cache contains outdated information. ## Deploy the workload with migration sidecar If your application uses user-assigned managed identity and still relies on IMDS to get an access token you can use the migration sidecar to start migrating to Microsoft Entra Workload ID. In long-term applications, you should modify the code to use the latest Azure Identity SDKs that support client assertion. To update or deploy the workload, add the following [pod annotations][pod-annotations] to your pod specification (only if you want to use the migration sidecar): | Pod annotation | Description | Value | | -------------- | ----------- | ----- | | `azure.workload.identity/inject-proxy-sidecar` | Indicates whether to inject the proxy sidecar into the pod. | `true` or `false` | | `azure.workload.identity/proxy-sidecar-port` | Desired port for the proxy sidecar. | Default value: `8000` | When you create a pod with these annotations, the Microsoft Entra Workload ID mutating webhook automatically injects the `init-container` and proxy sidecar to the pod spec. The following YAML shows an example of what the mutating webhook adds to the pod deployment: ```yml apiVersion: v1 kind: Pod metadata: name: httpbin-pod labels: app: httpbin azure.workload.identity/use: "true" annotations: azure.workload.identity/inject-proxy-sidecar: "true" spec: serviceAccountName: workload-identity-sa initContainers: - name: init-networking image: mcr.microsoft.com/oss/azure/workload-identity/proxy-init:v1.1.0 securityContext: capabilities: add: - NET_ADMIN drop: - ALL privileged: true runAsUser: 0 env: - name: PROXY_PORT value: "8000" containers: - name: nginx image: nginx:alpine ports: - containerPort: 80 - name: proxy image: mcr.microsoft.com/oss/azure/workload-identity/proxy:v1.1.0 ports: - containerPort: 8000 ``` ## Verify the workload with migration sidecar 1. Verify the pod is in a running state using the [`kubectl describe pod`][kubectl-describe] command. Replace `<pod-name>` with the name of your pod. ```bash kubectl describe pods <pod-name> ``` 1. Verify the pod is passing IMDS transactions using the [`kubectl logs`][kubelet-logs] command. Replace `<pod-name>` with the name of your pod. ```bash kubectl logs <pod-name> ``` The following example log output resembles successful communication through the proxy sidecar. Verify the logs show a token is successfully acquired and the `GET` operation is successful. ```output I0926 00:29:29.968723 1 proxy.go:97] proxy "msg"="starting the proxy server" "port"=8080 "userAgent"="azure-workload-identity/proxy/v0.13.0-12-gc8527f3 (linux/amd64) c8527f3/2022-09-26-00:19" I0926 00:29:29.972496 1 proxy.go:173] proxy "msg"="received readyz request" "method"="GET" "uri"="/readyz" I0926 00:29:30.936769 1 proxy.go:107] proxy "msg"="received token request" "method"="GET" "uri"="/metadata/identity/oauth2/token?resource=https://management.core.windows.net/api-version=2018-02-01&client_id=<client_id>" I0926 00:29:31.101998 1 proxy.go:129] proxy "msg"="successfully acquired token" "method"="GET" "uri"="/metadata/identity/oauth2/token?resource=https://management.core.windows.net/api-version=2018-02-01&client_id=<client_id>" ``` ## Remove pod-managed identity After you complete your testing and the application can successfully get a token using the proxy sidecar, you can remove the identity and pod-managed identity mapping from your AKS cluster - Remove the pod-managed identity binding from your pod using the [`az aks pod-identity delete`][az-aks-pod-identity-delete] command. Replace `<pod-identity-name>` and `<pod-identity-namespace>` with the name and namespace of your pod identity. ```azurecli-interactive az aks pod-identity delete --name <pod-identity-name> --namespace <pod-identity-namespace> --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME ``` ## Related content For more information about Microsoft Entra Workload ID, see the [Overview][workload-identity-overview] article. <!-- INTERNAL LINKS --> [pod-annotations]: workload-identity-overview.md#pod-annotations [az-identity-create]: /cli/azure/identity#az-identity-create [az-account-set]: /cli/azure/account#az-account-set [az-aks-get-credentials]: /cli/azure/aks#az-aks-get-credentials [workload-identity-overview]: workload-identity-overview.md [az-identity-federated-credential-create]: /cli/azure/identity/federated-credential#az-identity-federated-credential-create [az-aks-pod-identity-delete]: /cli/azure/aks/pod-identity#az-aks-pod-identity-delete [azure-identity-supported-versions]: workload-identity-overview.md#prerequisites [azure-identity-libraries]: /entra/identity-platform/reference-v2-libraries [openid-connect-overview]: /azure/active-directory/develop/v2-protocols-oidc [install-azure-cli]: /cli/azure/install-azure-cli [assign-rbac-managed-identity]: /azure/role-based-access-control/role-assignments-portal-managed-identity [az-identity-show]: /cli/azure/identity#az-identity-show [az-aks-show]: /cli/azure/aks#az-aks-show <!-- EXTERNAL LINKS --> [kubectl-describe]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#describe [kubelet-logs]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs
Success! Branch created successfully. Create Pull Request on GitHub
Error: