Example for using Microsoft Entra Workload ID in OpenShift Container Platform
Environment
- Red Hat OpenShift Container Platform (OCP) 4.14 and later
- Important Note: Azure Red Hat OpenShift clusters do not currently support Microsoft Entra (formerly Azure Active Directory) Workload ID.
- Microsoft Azure
Issue
- How can Microsoft Entra (formerly Azure Active Directory) Workload ID be used with workload running on OpenShift Container Platform?
- Is there an example for using Microsoft Entra Workload ID?
Resolution
- Prerequisites: Microsoft Entra (formerly Azure Active Directory) Workload ID is only available with OpenShift Container Platform 4.14 and later. For more information about the short-term credentials implementation for OpenShift Container Platform clusters on Azure, see the OpenShift documentation.
- Important Note: Azure Red Hat OpenShift clusters do not currently support Microsoft Entra (formerly Azure Active Directory) Workload ID.
Example
This example deploys an application that will access a Microsoft Azure Key Vault by using Microsoft Entra Workload ID.
-
Verify that the annotation
target.workload.openshift.io/management
is set on thepod-identity-webhook
Deployment in the `` namespace:$ oc describe deployment pod-identity-webhook -n openshift-cloud-credential-operator | grep 'target.workload.openshift.io/management' Annotations: target.workload.openshift.io/management: {"effect": "PreferredDuringScheduling"}
-
Begin by setting environment variables matching your Azure environment. Make sure to set the correct
RESOURCE_GROUP
,LOCATION
and correct namespaces and desired identity names:export KEYVAULT_NAME="azwi-kv-$(openssl rand -hex 2)" export KEYVAULT_SECRET_NAME="my-secret" export RESOURCE_GROUP="<AZURE_RESOURCE_GROUP>" export LOCATION="northeurope" export USER_ASSIGNED_IDENTITY_NAME="example-webhook-identity" export SERVICE_ACCOUNT_NAMESPACE="example-project" export SERVICE_ACCOUNT_NAME="example-workload-identity-sa"
-
Obtain the clusters
serviceAccountIssuer
OIDC Issuer URL and set the environment variable:export SERVICE_ACCOUNT_ISSUER=`oc get authentication cluster -o jsonpath --template='{ .spec.serviceAccountIssuer }'`
Verify that the correct URL has been set:
echo $SERVICE_ACCOUNT_ISSUER https://exampleinfra.blob.core.windows.net/exampleinfra
-
In this example, a new Microsoft Azure Key Vault with a new secret is created that is later accessed via Microsoft Entra Workload ID. Use the Azure
az
command line tool to create the key vault that is later accessed:# If necessary, create the Resource Group (this may not be necessary) az group create --name "${RESOURCE_GROUP}" --location "${LOCATION}" # Create the Keyvault and set a secret value az keyvault create --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --name "${KEYVAULT_NAME}" az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value "Hello world"
-
In these next steps, an Azure user-assigned managed identity and the corresponding policy access is created:
# Create the identity az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" # Set policy access for user-assigned managed identity export USER_ASSIGNED_IDENTITY_CLIENT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'clientId' -otsv)" export USER_ASSIGNED_IDENTITY_OBJECT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'principalId' -otsv)" az keyvault set-policy --name "${KEYVAULT_NAME}" --secret-permissions get --object-id "${USER_ASSIGNED_IDENTITY_OBJECT_ID}"
-
In OpenShift Container Platform, create the Service Account with the
azure.workload.identity/client-id
set to theUSER_ASSIGNED_IDENTITY_CLIENT_ID
above:apiVersion: v1 kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: ${APPLICATION_CLIENT_ID:-$USER_ASSIGNED_IDENTITY_CLIENT_ID} name: ${SERVICE_ACCOUNT_NAME} namespace: ${SERVICE_ACCOUNT_NAMESPACE}
-
As the last step, create an Azure federated identity credential linking the service account in OpenShift Container Platform to the Azure user-assigned managed identity:
az identity federated-credential create \ --name "kubernetes-federated-credential" \ --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \ --resource-group "${RESOURCE_GROUP}" \ --issuer "${SERVICE_ACCOUNT_ISSUER}" \ --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
-
The OpenShift Container Platform Service Account is now configured as expected. Note that both the
.spec.serviceAccountName
is set and also the labelazure.workload.identity/use: "true"
is used:export KEYVAULT_URL="$(az keyvault show -g ${RESOURCE_GROUP} -n ${KEYVAULT_NAME} --query properties.vaultUri -o tsv)" cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: quick-start namespace: ${SERVICE_ACCOUNT_NAMESPACE} labels: azure.workload.identity/use: "true" spec: serviceAccountName: ${SERVICE_ACCOUNT_NAME} securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - image: ghcr.io/azure/azure-workload-identity/msal-go name: oidc securityContext: allowPrivilegeEscalation: false capabilities: drop: [ "ALL" ] env: - name: KEYVAULT_URL value: ${KEYVAULT_URL} - name: SECRET_NAME value: ${KEYVAULT_SECRET_NAME} EOF
-
In the newly deployed workload, verify that there are both the environment variables and also a projected volume set:
oc describe pod quick-start [..] Environment: KEYVAULT_URL: https://azwi-kv-45ff.vault.azure.net/ SECRET_NAME: my-secret AZURE_CLIENT_ID: 13698e96-e041-417e-9a7d-EXAMPLE AZURE_TENANT_ID: 6047c7e9-b2ad-488d-a54e-EXAMPLE AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/ [..] Volumes: [..] azure-identity-token: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3600
-
Verify in the logs that the workload was able to access the Microsoft Azure Key Vault using the injected keys:
$ oc logs quick-start I0816 09:43:37.961113 1 main.go:63] "successfully got secret" secret="Hello world"
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments