Skip to content

Commit 4514ac3

Browse files
authored
Merge pull request #16318 from sethmanheim/wk-ee1112
Add Edge Essentials workload identity article
2 parents ce86abf + c42a905 commit 4514ac3

File tree

2 files changed

+263
-0
lines changed

2 files changed

+263
-0
lines changed

AKS-Hybrid/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@
206206
href: aks-edge-howto-more-configs.md
207207
- name: Use GPU acceleration
208208
href: aks-edge-gpu.md
209+
- name: Configure Workload Identity
210+
href: aks-edge-workload-identity.md
209211
- name: Update AKS Edge Essentials
210212
items:
211213
- name: Update online
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
---
2+
title: Configure Workload Identity on an AKS Edge Essentials cluster (preview)
3+
description: Learn how to configure an AKS Edge Essentials cluster with workload identity.
4+
author: sethmanheim
5+
ms.author: sethm
6+
ms.topic: how-to
7+
ms.date: 11/15/2024
8+
9+
---
10+
11+
# Configure Workload Identity on an AKS Edge Essentials cluster (preview)
12+
13+
Azure Kubernetes Service (AKS) Edge Essentials is an on-premises Kubernetes implementation of Azure Kubernetes Service (AKS) that automates running containerized applications at scale. This article describes how to perform the following tasks:
14+
15+
- Create a Kubernetes service account and bind it to the Azure Managed Identity.
16+
- Create a federated credential on the managed identity to trust the OIDC issuer.
17+
- Deploy your application.
18+
- Example: Grant a pod in the cluster access to secrets in an Azure key vault.
19+
20+
> [!IMPORTANT]
21+
> These preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. Azure Kubernetes Service Edge Essentials previews are partially covered by customer support on a best-effort basis.
22+
23+
> [!NOTE]
24+
> In this public preview, AKS Edge Essentials allows you to enable workload identity during the initial deployment of the Azure IoT Operations quickstart script. This feature is not available for other AKS Edge Essentials scenarios.
25+
26+
## Prerequisites
27+
28+
Before using workload identity federation for an AKS Edge Essentials cluster, you must deploy the Azure IoT Operation quickstart script as described in [Create and configure an AKS Edge Essentials cluster that can run Azure IoT Operations](aks-edge-howto-deploy-azure-iot.md). The script automatically enables the workload identity federation feature on the AKS Edge Essentials cluster.
29+
30+
After you deploy the AKS Edge Essentials cluster, you can use the following command to check the status of the workload identity extension:
31+
32+
```azurecli
33+
az connectedk8s show -n $aks_cluster_name -g $resource_group_name
34+
```
35+
36+
```output
37+
# agentState = "Succeeded"
38+
"agentPublicKeyCertificate": "",
39+
"agentVersion": "1.21.10",
40+
"arcAgentProfile": {
41+
"agentAutoUpgrade": "Enabled",
42+
"agentErrors": [],
43+
"agentState": "Succeeded",
44+
"desiredAgentVersion": "",
45+
"systemComponents": null
46+
47+
# oidcIssuerProfile "enabled": true and "issuerUrl" present
48+
"oidcIssuerProfile": {
49+
"enabled": true,
50+
"issuerUrl": "https://oidcdiscovery-{location}-endpoint-1111111111111111.000.azurefd.net/00000000-0000-0000-0000-000000000000/11111111-1111-1111-1111-111111111111/",
51+
52+
# workloadIdentity "enabled": true
53+
"securityProfile": {
54+
"workloadIdentity": {
55+
"enabled": true
56+
```
57+
58+
In the Azure portal, you can view the `wiextension` extension under the **Properties** section of your Kubernetes cluster.
59+
60+
### Export environment variables
61+
62+
To help simplify the steps to configure the required identities, the following steps define environment variables that are referenced in the examples in this article. Remember to replace the values shown with your own values:
63+
64+
```azurecli
65+
$AZSubscriptionID = "00000000-0000-0000-0000-000000000000"
66+
$Location = "westeurope"
67+
$resource_group_name = "myResourceGroup"
68+
69+
$aks_cluster_name = "myAKSCluster"
70+
71+
$SERVICE_ACCOUNT_NAMESPACE = "default"
72+
$SERVICE_ACCOUNT_NAME = "workload-identity-sa"
73+
74+
$FedIdCredentialName = "myFedIdentity"
75+
$MSIName = "myIdentity"
76+
77+
# Include these variables to access key vault secrets from a pod in the cluster.
78+
$KVName = "KV-workload-id"
79+
$KVSecretName= "KV-secret"
80+
```
81+
82+
### Save the OIDC issuer URL to an environment variable
83+
84+
To get the OIDC issuer URL and save it to an environment variable, run the following command:
85+
86+
```azurecli
87+
$SERVICE_ACCOUNT_ISSUER =$(az connectedk8s show --n $aks_cluster_name --resource-group $resource_group_name --query "oidcIssuerProfile.issuerUrl" --output tsv)
88+
```
89+
90+
## Step 1: Create a Kubernetes service account and bind it to the Azure Managed Identity
91+
92+
First, call the [az identity create](/cli/azure/identity#az-identity-create) command to create a managed identity:
93+
94+
```azurecli
95+
az identity create --name $MSIName --resource-group $resource_group_name --location $Location --subscription $AZSubscriptionID
96+
```
97+
98+
Next, create variables for the managed identity's client ID:
99+
100+
```azurecli
101+
$MSIId=$(az identity show --resource-group $resource_group_name --name $MSIName --query 'clientId' --output tsv) 
102+
$MSIPrincipalId=$(az identity show --resource-group $resource_group_name --name $MSIName --query 'principalId' --output tsv)
103+
```
104+
105+
### Create a Kubernetes service account
106+
107+
Create a Kubernetes service account and annotate it with the client ID of the managed identity you created in the previous step. Copy and paste the following Azure CLI commands:
108+
109+
```azurecli
110+
$yaml = @"
111+
apiVersion: v1
112+
kind: ServiceAccount
113+
metadata:
114+
annotations:
115+
azure.workload.identity/client-id: $MSIId
116+
name: $SERVICE_ACCOUNT_NAME
117+
namespace: $SERVICE_ACCOUNT_NAMESPACE
118+
"@
119+
120+
# Replace variables within the YAML content
121+
$yaml = $yaml -replace '\$MSIId', $MSIId `
122+
-replace '\$SERVICE_ACCOUNT_NAME', $SERVICE_ACCOUNT_NAME `
123+
-replace '\$SERVICE_ACCOUNT_NAMESPACE', $SERVICE_ACCOUNT_NAMESPACE
124+
125+
# Apply the YAML content to Kubernetes
126+
$yaml | kubectl apply -f -
127+
```
128+
129+
The following output shows the workload identity created successfully:
130+
131+
```output
132+
serviceaccount/workload-identity-sa created
133+
```
134+
135+
## Step 2: Create a federated credential on the managed identity to trust the OIDC issuer
136+
137+
To create the federated identity credential between the managed identity, the service account issuer, and the subject, call the [az identity federated-credential create](/cli/azure/identity/federated-credential#az-identity-federated-credential-create) command. For more information about federated identity credentials in Microsoft Entra, see [Overview of federated identity credentials in Microsoft Entra ID](/cli/azure/identity/federated-credential#az-identity-federated-credential-create).
138+
139+
```azurecli
140+
# Create a federated credential
141+
az identity federated-credential create --name $FedIdCredentialName --identity-name $MSIName --resource-group $resource_group_name --issuer $SERVICE_ACCOUNT_ISSUER --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
142+
143+
# Show the federated credential
144+
az identity federated-credential show --name $FedIdCredentialName --resource-group $resource_group_name --identity-name $MSIName
145+
```
146+
147+
> [!NOTE]
148+
> After you add a federated identity credential, it takes a few seconds to propagate. Token requests made immediately afterward might fail until the cache refreshes. To prevent this issue, consider adding a brief delay after creating the federated identity credential.
149+
150+
## Step 3: Deploy your application
151+
152+
When you deploy your application pods, the manifest should reference the service account created in the **Create Kubernetes service account** step. The following manifest shows how to reference the account, specifically the `metadata\namespace` and `spec\serviceAccountName` properties. Make sure to specify an image for `image` and a container name
153+
for `containerName`:
154+
155+
```azurecli
156+
$image = "<image>" # Replace <image> with the actual image name
157+
$containerName = "<containerName>" # Replace <containerName> with the actual container name
158+
159+
$yaml = @"
160+
apiVersion: v1
161+
kind: Pod
162+
metadata:
163+
name: sample-quick-start
164+
namespace: $SERVICE_ACCOUNT_NAMESPACE
165+
labels:
166+
azure.workload.identity/use: "true" # Required. Only pods with this label can use workload identity.
167+
spec:
168+
serviceAccountName: $SERVICE_ACCOUNT_NAME
169+
containers:
170+
- image: $image
171+
name: $containerName
172+
"@
173+
174+
# Replace variables within the YAML content
175+
$yaml = $yaml -replace '\$SERVICE_ACCOUNT_NAMESPACE', $SERVICE_ACCOUNT_NAMESPACE `
176+
-replace '\$SERVICE_ACCOUNT_NAME', $SERVICE_ACCOUNT_NAME
177+
178+
# Apply the YAML configuration
179+
$yaml | kubectl apply -f -
180+
```
181+
182+
> [!IMPORTANT]
183+
> Ensure that the application pods using workload identity include the label `azure.workload.identity/use: "true"` in the pod spec. Otherwise the pods fail after they restart.
184+
185+
## Example: Grant permissions to access Azure Key Vault
186+
187+
The instructions in this step describe how to access secrets, keys, or certificates in an Azure key vault from the pod. The examples in this section configure access to secrets in the key vault for the workload identity, but you can perform similar steps to configure access to keys or certificates.
188+
189+
The following example shows how to use the Azure role-based access control (Azure RBAC) permission model to grant the pod access to the key vault. For more information about the Azure RBAC permission model for Azure Key Vault, see [Grant permission to applications to access an Azure key vault using Azure RBAC](/azure/key-vault/general/rbac-guide).
190+
191+
1. Create a key vault with purge protection and RBAC authorization enabled. You can also use an existing key vault if it is configured for both purge protection and RBAC authorization:
192+
193+
```azurecli
194+
az keyvault create --name $KVName --resource-group $resource_group_name --location $Location --enable-purge-protection --enable-rbac-authorization
195+
196+
# retrieve the key vault ID for role assignment
197+
$KVId=$(az keyvault show --resource-group $resource_group_name --name $KVName --query id --output tsv)
198+
```
199+
200+
1. Assign the RBAC [Key Vault Secrets Officer](/azure/role-based-access-control/built-in-roles/security#key-vault-secrets-officer) role to yourself so that you can create a secret in the new key vault. New role assignments can take up to five minutes to propagate and be updated by the authorization server.
201+
202+
```azurecli
203+
az role assignment create --assignee-object-id $MSIPrincipalId --role "Key Vault Secrets Officer" --scope $KVId --assignee-principal-type ServicePrincipal
204+
```
205+
206+
1. Create a secret in the key vault:
207+
208+
```azurecli
209+
az keyvault secret set --vault-name $KVName --name $KVSecretName --value "Hello!"
210+
```
211+
212+
1. Assign the [Key Vault Secrets User](/azure/role-based-access-control/built-in-roles/security#key-vault-secrets-user) role to the user-assigned managed identity that you created previously. This step gives the managed identity permission to read secrets from the key vault:
213+
214+
```azurecli
215+
az role assignment create --assignee-object-id $MSIPrincipalId --role "Key Vault Secrets User" --scope $KVId --assignee-principal-type ServicePrincipal
216+
```
217+
218+
1. Create an environment variable for the key vault URL:
219+
220+
```azurecli
221+
$KVUrl=$(az keyvault show --resource-group $resource_group_name --name $KVName --query properties.vaultUri --output tsv)
222+
```
223+
224+
1. Deploy a pod that references the service account and key vault URL:
225+
226+
```azurecli
227+
$yaml = @"
228+
apiVersion: v1
229+
kind: Pod
230+
metadata:
231+
name: sample-quick-start
232+
namespace: $SERVICE_ACCOUNT_NAMESPACE
233+
labels:
234+
azure.workload.identity/use: "true"
235+
spec:
236+
serviceAccountName: $SERVICE_ACCOUNT_NAME
237+
containers:
238+
- image: ghcr.io/azure/azure-workload-identity/msal-go
239+
name: oidc
240+
env:
241+
- name: KEYVAULT_URL
242+
value: $KVUrl
243+
- name: SECRET_NAME
244+
value: $KVSecretName
245+
nodeSelector:
246+
kubernetes.io/os: linux
247+
"@
248+
249+
# Replace variables within the YAML content
250+
$yaml = $yaml -replace '\$SERVICE_ACCOUNT_NAMESPACE', $SERVICE_ACCOUNT_NAMESPACE `
251+
-replace '\$SERVICE_ACCOUNT_NAME', $SERVICE_ACCOUNT_NAME `
252+
-replace '\$KVUrl', $KVUrl `
253+
-replace '\$KVSecretName', $KVSecretName
254+
255+
# Apply the YAML configuration
256+
$yaml | kubectl --kubeconfig $aks_cluster_name apply -f -
257+
```
258+
259+
## Next steps
260+
261+
In this article, you configured it to use a workload identity in preparation for application workloads to authenticate with that credential. Now you're ready to deploy your application and configure it to use the workload identity with the latest version of the [Azure Identity client library](/azure/active-directory/develop/reference-v2-libraries).

0 commit comments

Comments
 (0)