Problem Statement
You have an application running in Azure Kubernetes Service (AKS) that needs to access other Azure services. You don't want to use connection string with secrets in the code. You don't want to use service principal with secrets in the code. You want to use managed identities to authenticate to the Azure services. How do you do this in AKS?
Basics
Two types of identities:
Application identities: More ownership, need to create secrets for authentication.
Managed identities: Less ownership, no need to create secrets for authentication. (Azure platform manages the secrets).
Within managed identities, there are two types:
System assigned managed identity: Managed by Azure platform. Attached to the resource. The resource is the owner of the identity.
User assigned managed identity: Managed by Azure platform. Attached to the resource. The resource is not the owner of the identity. The identity can be attached to multiple resources.
Azure VMs, Azure App Services, Azure Container Apps, Azure Functions, etc. These are all first party services in Azure. User assigned managed identities can be used in these services (or attached to these services).
Services such as AKS can host multiple applications and services. Kubernetes service accounts are the identity mechanism in Kubernetes for applications. Workload identity is a way to map managed identities to Kubernetes service accounts.
Federated credential creates this linkage:
az identity federated-credential create --name fedcredentialname --identity-name USER_ASSIGNED_IDENTITY_NAME --resource-group --issuer "${AKS_OIDC_ISSUER}" --subject system:serviceaccount:namespace:serviceaccount --audience api://AzureADTokenExchange
Scenario
Let's use the following scenario to understand the workload identity.
Upload blob to a storage account from a pod in AKS. This application is running in a pod in AKS. The application needs to authenticate to the storage account to upload the blob. The application is using the managed identity to authenticate to the storage account. This applican can also be run in local machine.
Steps
Refer this github repo for step by step instructions:
https://github.com/srinman/azureexamples/tree/main/aks/workloadidentity
This repo has pythonblobdac.py and pythonblobwic.py files. The pythonblobdac.py file uses the Azure default credentials to authenticate to the Azure services. The pythonblobwic.py file uses the workload identity to authenticate to the Azure services.
Create a storage account and a container called 'workloadidentity' in the storage account.
Provide IAM role 'Storage Blob Data Contributor' to the user assigned managed identity and for the user who is running the python code in local machine.
DefaultAzureCredential
pythonblobdac
When this program is called from command line directly with the command below python pythonblobdac.py
It uses the developers to use their own accounts to authenticate to Azure services.
from azure.identity import DefaultAzureCredential ... default_credential = DefaultAzureCredential() ... blob_service_client = BlobServiceClient(account_url, credential=default_credential)
DefaultAzureCredential attempts to authenticate via the following mechanisms, in this order, stopping when one succeeds: (read the link below for more details)
https://learn.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python#defaultazurecredential
In case of calling program from command line, it uses the developers account to authenticate to the Azure services. It's number#4 in the doc (excerpt below)
Azure CLI - If a user has signed in via the Azure CLI az login command, DefaultAzureCredential will authenticate as that user.
When the same code is called from a pod in AKS, it uses workload identity to authenticate to the Azure services. It's number#2 in the doc (excerpt below) Workload Identity - If the application is deployed to Azure Kubernetes Service with Managed Identity enabled, DefaultAzureCredential will authenticate with it.
Python code remains same. so in a way, the code is portable. It can be run in local machine or in AKS. The only difference is how the code authenticates to the Azure services.
Workload Identity
pythonblobwic
In this program, only difference is that it uses WorkloadIdentityCredential() vs DefaultAzureCredential(). The rest of the code remains same. This also means that the code can only be run in AKS. It cannot be run in local machine.
References
https://blog.identitydigest.com/azuread-federate-mi/
https://github.com/Azure/azure-sdk-for-python/tree/azure-identity_1.17.1/sdk/identity/azure-identity
https://azure.github.io/azure-sdk-for-python/
https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob