Skip to content

Commit 23449ef

Browse files
committed
Fix identity doc
1 parent 834ade0 commit 23449ef

File tree

1 file changed

+83
-201
lines changed

1 file changed

+83
-201
lines changed

scenarios/azure-aks-docs/articles/aks/workload-identity-migrate-from-pod-identity.md

Lines changed: 83 additions & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -11,208 +11,115 @@ ms.author: nickoman
1111

1212
# Migrate from pod managed-identity to workload identity
1313

14-
This article focuses on migrating from a pod-managed identity to Microsoft Entra Workload ID for your Azure Kubernetes Service (AKS) cluster. It also provides guidance depending on the version of the [Azure Identity][azure-identity-supported-versions] client library used by your container-based application.
14+
## Create resource group
15+
Set your subscription to be the current active subscription using the `az account set` command. Then, create a random suffix to ensure unique resource names.
1516

16-
If you aren't familiar with Microsoft Entra Workload ID, see the [Overview][workload-identity-overview] article.
17-
18-
## Before you begin
19-
20-
Ensure you have the Azure CLI version 2.47.0 or later installed. Run the `az --version` command to find the version
21-
22-
If you need to install or upgrade, see [Install Azure CLI][install-azure-cli].
23-
24-
## Migration scenarios
25-
26-
This section explains the migration options available depending on what version of the Azure Identity SDK is installed.
27-
28-
For either scenario, you need to have the federated trust set up before you update your application to use the workload identity. The following are the minimum steps required:
29-
30-
- Create a managed identity credential.
31-
- Associate the managed identity with the Kubernetes service account already used for the pod-managed identity or create a new Kubernetes service account and then associate it with the managed identity.
32-
- Establish a federated trust relationship between the managed identity and Microsoft Entra ID.
33-
34-
### Migrate from latest version
35-
36-
If your application is already using the latest version of the Azure Identity SDK, perform the following steps to complete the authentication configuration:
37-
38-
- Deploy workload identity in parallel with pod-managed identity. You can restart your application deployment to begin using the workload identity, where it injects the OIDC annotations into the application automatically.
39-
- After verifying the application is able to authenticate successfully, you can remove the pod-managed identity annotations from your application and then remove the pod-managed identity add-on.
40-
41-
### Migrate from older version
42-
43-
If your application isn't using the latest version of the Azure Identity SDK, you have two options:
44-
45-
- Use a migration sidecar that we provide within your Linux applications, which proxies the IMDS transactions your application makes over to [OpenID Connect][openid-connect-overview] (OIDC). The migration sidecar isn't intended to be a long-term solution, but a way to get up and running quickly on workload identity. Perform the following steps:
46-
47-
- Deploy the workload with migration sidecar to proxy the application IMDS transactions.
48-
- Verify the authentication transactions are completing successfully.
49-
- Schedule the work for the applications to update their SDKs to a supported version.
50-
- Once the SDKs are updated to the supported version, you can remove the proxy sidecar and redeploy the application.
51-
52-
> [!NOTE]
53-
> The migration sidecar is **not supported for production use**. This feature is meant to give you time to migrate your application SDKs to a supported version, and not meant or intended to be a long-term solution.
54-
> The migration sidecar is only available for Linux containers, due to only providing pod-managed identities with Linux node pools.
55-
56-
- Rewrite your application to support the latest version of the [Azure Identity][azure-identity-supported-versions] client library. Afterwards, perform the following steps:
57-
58-
- Restart your application deployment to begin authenticating using the workload identity.
59-
- Once you verify the authentication transactions are completing successfully, you can remove the pod-managed identity annotations from your application and then remove the pod-managed identity add-on.
60-
61-
## Create a managed identity
62-
63-
If you don't have a managed identity created and assigned to your pod, perform the following steps to create and grant the necessary permissions to storage, Key Vault, or whatever resources your application needs to authenticate with in Azure.
64-
65-
1. Set your subscription to be the current active subscription using the `az account set` command. Then, create a random suffix to ensure unique resource names.
66-
67-
```bash
68-
export RANDOM_SUFFIX=$(openssl rand -hex 3)
69-
```
70-
71-
3. Create a resource group.
72-
73-
```bash
74-
export RESOURCE_GROUP_NAME="myResourceGroup$RANDOM_SUFFIX"
75-
export LOCATION="WestUS2"
76-
az group create --name "$RESOURCE_GROUP_NAME" --location "$LOCATION"
77-
```
78-
79-
Results:
80-
81-
<!-- expected_similarity=0.3 -->
82-
83-
```json
84-
{
85-
"id": "/subscriptions/xxxxx/resourceGroups/myResourceGroupxxx",
86-
"location": "<location>",
87-
"managedBy": null,
88-
"name": "myResourceGroupxxx",
89-
"properties": {
90-
"provisioningState": "Succeeded"
91-
},
92-
"tags": null,
93-
"type": "Microsoft.Resources/resourceGroups"
94-
}
95-
```
96-
97-
4. Create a managed identity.
98-
99-
```bash
100-
export IDENTITY_NAME="userAssignedIdentity$RANDOM_SUFFIX"
101-
az identity create --name "$IDENTITY_NAME" --resource-group "$RESOURCE_GROUP_NAME" --location "$LOCATION"
102-
```
103-
104-
Results:
105-
106-
<!-- expected_similarity=0.3 -->
107-
108-
```json
109-
{
110-
"clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
111-
"id": "/subscriptions/xxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.ManagedIdentity/userAssignedIdentities/userAssignedIdentityxxx",
112-
"location": "<location>",
113-
"name": "userAssignedIdentityxxx",
114-
"principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
115-
"resourceGroup": "myResourceGroupxxx",
116-
"tags": {},
117-
"type": "Microsoft.ManagedIdentity/userAssignedIdentities"
118-
}
119-
```
120-
121-
5. Save the client ID of the managed identity to an environment variable.
122-
123-
```bash
124-
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "$RESOURCE_GROUP_NAME" --name "$IDENTITY_NAME" --query 'clientId' -o tsv)"
125-
```
126-
127-
6. Grant the managed identity the permissions required to access the resources in Azure it requires. For information on how to do this, see [Assign a managed identity access to a resource][assign-rbac-managed-identity].
128-
129-
7. Get the OIDC Issuer URL and save it to an environment variable. Replace the default values for the cluster name and the resource group name.
17+
```bash
18+
export RANDOM_SUFFIX=$(openssl rand -hex 3)
19+
export RESOURCE_GROUP_NAME="myResourceGroup$RANDOM_SUFFIX"
20+
export LOCATION="WestUS2"
21+
az group create --name "$RESOURCE_GROUP_NAME" --location "$LOCATION"
22+
```
13023

131-
```bash
132-
export AKS_CLUSTER_NAME=$MY_AKS_CLUSTER_NAME
133-
export AKS_RESOURCE_GROUP=$MY_AKS_RESOURCE_GROUP
134-
export AKS_OIDC_ISSUER="$(az aks show --name "$AKS_CLUSTER_NAME" --resource-group "$AKS_RESOURCE_GROUP" --query "oidcIssuerProfile.issuerUrl" -o tsv)"
135-
```
24+
Results:
25+
26+
<!-- expected_similarity=0.3 -->
27+
28+
```json
29+
{
30+
"id": "/subscriptions/xxxxx/resourceGroups/myResourceGroupxxx",
31+
"location": "<location>",
32+
"managedBy": null,
33+
"name": "myResourceGroupxxx",
34+
"properties": {
35+
"provisioningState": "Succeeded"
36+
},
37+
"tags": null,
38+
"type": "Microsoft.Resources/resourceGroups"
39+
}
40+
```
13641

137-
The variable should contain the Issuer URL similar to the following example:
42+
## Create a managed identity.
13843

139-
```bash
140-
echo "$AKS_OIDC_ISSUER"
141-
```
44+
```bash
45+
export IDENTITY_NAME="userAssignedIdentity$RANDOM_SUFFIX"
46+
az identity create --name "$IDENTITY_NAME" --resource-group "$RESOURCE_GROUP_NAME" --location "$LOCATION"
47+
```
14248

143-
Results:
49+
Results:
50+
51+
<!-- expected_similarity=0.3 -->
52+
53+
```json
54+
{
55+
"clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
56+
"id": "/subscriptions/xxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.ManagedIdentity/userAssignedIdentities/userAssignedIdentityxxx",
57+
"location": "<location>",
58+
"name": "userAssignedIdentityxxx",
59+
"principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
60+
"resourceGroup": "myResourceGroupxxx",
61+
"tags": {},
62+
"type": "Microsoft.ManagedIdentity/userAssignedIdentities"
63+
}
64+
```
14465

145-
<!-- expected_similarity=0.3 -->
66+
## Get Client ID
14667

147-
```output
148-
https://eastus.oic.prod-aks.azure.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/
149-
```
68+
Save the client ID of the managed identity to an environment variable.
15069

151-
By default, the Issuer is set to use 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.
70+
```bash
71+
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "$RESOURCE_GROUP_NAME" --name "$IDENTITY_NAME" --query 'clientId' -o tsv)"
72+
```
15273

153-
## Create Kubernetes service account
74+
## Save OIDC Issuer URL
75+
Get the OIDC Issuer URL and save it to an environment variable.By default, the Issuer is set to use 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.
15476

155-
If you don't have a dedicated Kubernetes service account created for this application, perform the following steps to create and then annotate it with the client ID of the managed identity created in the previous step.
77+
```bash
78+
export AKS_CLUSTER_NAME=$MY_AKS_CLUSTER_NAME
79+
export AKS_RESOURCE_GROUP=$MY_AKS_RESOURCE_GROUP
80+
export AKS_OIDC_ISSUER="$(az aks show --name "$AKS_CLUSTER_NAME" --resource-group "$AKS_RESOURCE_GROUP" --query "oidcIssuerProfile.issuerUrl" -o tsv)"
81+
```
15682

157-
1. Get the Kubernetes credentials for your cluster.
83+
## Load credentials
15884

159-
```bash
160-
az aks get-credentials --name "$AKS_CLUSTER_NAME" --resource-group "$AKS_RESOURCE_GROUP"
161-
```
85+
Get the Kubernetes credentials for your cluster.
16286

163-
2. Create a namespace if you don't have one.
87+
```bash
88+
az aks get-credentials --name "$AKS_CLUSTER_NAME" --resource-group "$AKS_RESOURCE_GROUP"
89+
```
16490

165-
```bash
166-
export SERVICE_ACCOUNT_NAMESPACE="mynamespace$RANDOM_SUFFIX"
167-
kubectl create namespace "$SERVICE_ACCOUNT_NAMESPACE"
168-
```
91+
## Create Namespace
16992

170-
3. Create the service account and annotate it with the client ID of the managed identity.
93+
Create a namespace.
17194

172-
```bash
173-
export SERVICE_ACCOUNT_NAME="myserviceaccount$RANDOM_SUFFIX"
174-
kubectl create serviceaccount "$SERVICE_ACCOUNT_NAME" -n "$SERVICE_ACCOUNT_NAMESPACE"
175-
kubectl annotate serviceaccount "$SERVICE_ACCOUNT_NAME" --namespace "$SERVICE_ACCOUNT_NAMESPACE" azure.workload.identity/client-id="$USER_ASSIGNED_CLIENT_ID"
176-
```
95+
```bash
96+
export SERVICE_ACCOUNT_NAMESPACE="mynamespace$RANDOM_SUFFIX"
97+
kubectl create namespace "$SERVICE_ACCOUNT_NAMESPACE"
98+
```
17799

178-
The following output resembles successful creation of the service account:
100+
## Create Service Account
101+
Create the service account and annotate it with the client ID of the managed identity.
179102

180-
```output
181-
serviceaccount/<service-account-name> annotated
182-
```
103+
```bash
104+
export SERVICE_ACCOUNT_NAME="myserviceaccount$RANDOM_SUFFIX"
105+
kubectl create serviceaccount "$SERVICE_ACCOUNT_NAME" -n "$SERVICE_ACCOUNT_NAMESPACE"
106+
kubectl annotate serviceaccount "$SERVICE_ACCOUNT_NAME" --namespace "$SERVICE_ACCOUNT_NAMESPACE" azure.workload.identity/client-id="$USER_ASSIGNED_CLIENT_ID"
107+
```
183108

184109
## Establish federated identity credential trust
185110

186111
Establish a federated identity credential between the managed identity, the service account issuer, and the subject.
187112

188-
1. Create the federated identity credential. Replace the values `federated-identity-name`, `service-account-namespace`, and `service-account-name`.
189-
190-
```bash
191-
export FEDERATED_CREDENTIAL_NAME="myFederatedCredentialName$RANDOM_SUFFIX"
192-
az identity federated-credential create --name "$FEDERATED_CREDENTIAL_NAME" --identity-name "$IDENTITY_NAME" --resource-group "$RESOURCE_GROUP_NAME" --issuer "$AKS_OIDC_ISSUER" --subject "system:serviceaccount:$SERVICE_ACCOUNT_NAMESPACE:$SERVICE_ACCOUNT_NAME" --audience "api://AzureADTokenExchange"
193-
```
194-
195-
> [!NOTE]
196-
> It takes a few seconds for the federated identity credential to be propagated after being initially added. If a token request is made immediately after adding the federated identity credential, it might lead to failure for a couple of minutes as the cache is populated in the directory with old data. To avoid this issue, you can add a slight delay after adding the federated identity credential.
113+
```bash
114+
export FEDERATED_CREDENTIAL_NAME="myFederatedCredentialName$RANDOM_SUFFIX"
115+
az identity federated-credential create --name "$FEDERATED_CREDENTIAL_NAME" --identity-name "$IDENTITY_NAME" --resource-group "$RESOURCE_GROUP_NAME" --issuer "$AKS_OIDC_ISSUER" --subject "system:serviceaccount:$SERVICE_ACCOUNT_NAMESPACE:$SERVICE_ACCOUNT_NAME" --audience "api://AzureADTokenExchange"
116+
```
197117

198118
## Deploy the workload with migration sidecar
199119

200-
If your application is using managed identity and still relies on IMDS to get an access token, you can use the workload identity migration sidecar to start migrating to workload identity. This sidecar is a migration solution and in the long-term, applications should modify their code to use the latest Azure Identity SDKs that support client assertion.
201-
202-
To update or deploy the workload, add the following pod annotations to use the migration sidecar in your pod specification:
203-
204-
- `azure.workload.identity/inject-proxy-sidecar` - value is `"true"` or `"false"`
205-
- `azure.workload.identity/proxy-sidecar-port` - value is the desired port for the proxy sidecar. The default value is `"8000"`.
206-
207-
When a pod with the above annotations is created, the Azure Workload Identity mutating webhook automatically injects the init-container and proxy sidecar to the pod spec.
208-
209-
Here's an example of the mutated pod spec:
210-
211120
```bash
212121
export POD_NAME="httpbin-pod"
213-
```
214122

215-
```bash
216123
cat <<EOF > pod.yaml
217124
apiVersion: v1
218125
kind: Pod
@@ -237,44 +144,19 @@ spec:
237144
- name: IMDS_ENDPOINT
238145
value: "http://169.254.169.254"
239146
EOF
240-
```
241-
242-
After updating or deploying your application, verify the pod is in a running state using the [kubectl describe pod][kubectl-describe] command. Replace `$POD_NAME` with the name of your deployed pod.
243-
244-
Apply the pod specification:
245-
246-
```bash
247147
kubectl apply -f pod.yaml
248148
kubectl wait --for=condition=Ready pod/httpbin-pod -n "$SERVICE_ACCOUNT_NAMESPACE" --timeout=120s
249-
```
250-
251-
```bash
252-
253149
kubectl describe pods $POD_NAME -n "$SERVICE_ACCOUNT_NAMESPACE"
254-
```
255-
256-
To verify that the pod is passing IMDS transactions, use the [kubectl logs][kubelet-logs] command.
257-
258-
```bash
259150
kubectl logs $POD_NAME -n "$SERVICE_ACCOUNT_NAMESPACE"
260151
```
261152

262-
The following log output resembles successful communication through the proxy sidecar. Verify that the logs show a token is successfully acquired and the GET operation is successful.
263-
264-
```output
265-
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"
266-
I0926 00:29:29.972496 1 proxy.go:173] proxy "msg"="received readyz request" "method"="GET" "uri"="/readyz"
267-
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=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
268-
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=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
269-
```
270-
271153
## Remove pod-managed identity
272154

273155
After you've completed your testing and the application is successfully able to get a token using the proxy sidecar, you can remove the Microsoft Entra pod-managed identity mapping for the pod from your cluster, and then remove the identity.
274156

275-
1. Remove the identity from your pod. This should only be done after all pods in the namespace using the pod-managed identity mapping have migrated to use the sidecar.
276-
277-
Use the `az aks pod-identity delete` command to delete the pod-managed identity. Ensure you replace `<pod-managed-identity-name>` with the name of the pod-managed identity you wish to delete.
157+
```bash
158+
az aks pod-identity delete $IDENTITY_NAME
159+
```
278160

279161
## Next steps
280162

0 commit comments

Comments
 (0)