File: readme.md

package info (click to toggle)
python-azure 20230112%2Bgit-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 749,544 kB
  • sloc: python: 6,815,827; javascript: 287; makefile: 195; xml: 109; sh: 105
file content (195 lines) | stat: -rw-r--r-- 6,611 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# Testing managed identity in Azure Kubernetes Service

## Prerequisite tools
- Azure CLI
  - https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest
- Docker CLI
  - https://hub.docker.com/search?q=&type=edition&offering=community
- Helm 3.x
  - https://helm.sh/docs/intro/install/


## Azure resources
This test requires instances of these Azure resources:
- Azure Key Vault
- Azure Managed Identity
  - with secrets/set and secrets/delete permission for the Key Vault
- Azure Container Registry
- Azure Kubernetes Service
  - RBAC requires additional configuration not provided here, so an RBAC-disabled cluster is preferable
  - the cluster's service principal must have 'Managed Identity Operator' role over the managed identity
  - must be able to pull from the Container Registry

The rest of this section is a walkthrough of deploying these resources.

### Set environment variables to simplify copy-pasting
- RESOURCE_GROUP
  - name of an Azure resource group
  - must be unique in the Azure subscription
  - e.g. 'pod-identity-test'
- AKS_NAME
  - name of an Azure Kubernetes Service
  - must be unique in the resource group
  - e.g. 'pod-identity-test'
- ACR_NAME
  - name of an Azure Container Registry
  - 5-50 alphanumeric characters
  - must be globally unique
- MANAGED_IDENTITY_NAME
  - 3-128 alphanumeric characters
  - must be unique in the resource group
- KEY_VAULT_NAME
  - 3-24 alphanumeric characters
  - must begin with a letter
  - must be globally unique

### Create resource group
```sh
az group create -n $RESOURCE_GROUP --location westus2
```

### Create managed identity
Create the managed identity:
```sh
az identity create -g $RESOURCE_GROUP -n $MANAGED_IDENTITY_NAME
```

Save its `clientId`, `id` (ARM URI), and `principalId` (object ID) for later:
```sh
export MANAGED_IDENTITY_CLIENT_ID=$(az identity show -g $RESOURCE_GROUP -n $MANAGED_IDENTITY_NAME --query clientId -o tsv) \
       MANAGED_IDENTITY_ID=$(az identity show -g $RESOURCE_GROUP -n $MANAGED_IDENTITY_NAME --query id -o tsv) \
       MANAGED_IDENTITY_PRINCIPAL_ID=$(az identity show -g $RESOURCE_GROUP -n $MANAGED_IDENTITY_NAME --query principalId -o tsv)
```

### Create key vault
Create the Vault:
```sh
az keyvault create -g $RESOURCE_GROUP -n $KEY_VAULT_NAME --sku standard
```

Add an access policy for the managed identity:
```sh
az keyvault set-policy -n $KEY_VAULT_NAME --object-id $MANAGED_IDENTITY_PRINCIPAL_ID --secret-permissions list
```

### Create container registry
```sh
az acr create -g $RESOURCE_GROUP -n $ACR_NAME --admin-enabled --sku basic
```

### Create Kubernetes cluster
Deploy the cluster (this will take several minutes):
```sh
az aks create -g $RESOURCE_GROUP -n $AKS_NAME --generate-ssh-keys --node-count 1 --disable-rbac --attach-acr $ACR_NAME --enable-managed-identity
```

Save information about the cluster's node resource group:
```sh
export NODE_RESOURCE_GROUP=$(az aks show -g $RESOURCE_GROUP -n $AKS_NAME --query nodeResourceGroup -o tsv)
export NODE_RESOURCE_GROUP_SCOPE=$(az group show -n $NODE_RESOURCE_GROUP --query id -o tsv)
export KUBELET_IDENTITY_CLIENT_ID=$(az aks show -g $RESOURCE_GROUP -n $AKS_NAME --query identityProfile.kubeletidentity.clientId -o tsv)

```

### Create role assignments
Assign needed roles to the cluster managed identity:
```sh
az role assignment create --role "Managed Identity Operator" --assignee $KUBELET_IDENTITY_CLIENT_ID --scope $MANAGED_IDENTITY_ID
```

Add role assignments required by AAD Pod Identity:
```sh
az role assignment create --role "Managed Identity Operator" --assignee $KUBELET_IDENTITY_CLIENT_ID --scope $NODE_RESOURCE_GROUP_SCOPE
az role assignment create --role "Virtual Machine Contributor" --assignee $KUBELET_IDENTITY_CLIENT_ID --scope $NODE_RESOURCE_GROUP_SCOPE

```

**Note**: Sometimes the role assignments can take several minutes to propagate which may cause `Init:Error` statuses in the test pod
if the tests are run too soon after the role assignments are created. If this is encountered, wait a few more minutes and try again.

## Build images
The test application must be packaged as a Docker image before deployment.
Test runs must include Python 3.7+.

### Authenticate to ACR
```sh
az acr login -n $ACR_NAME
```

### Acquire the test code
```sh
git clone https://github.com/Azure/azure-sdk-for-python/ --branch main --single-branch --depth 1
```

The rest of this section assumes this working directory:
```sh
cd azure-sdk-for-python/sdk/identity/azure-identity/tests
```

### Build image and push them to the container registry
Set environment variables:
```sh
export REPOSITORY=$ACR_NAME.azurecr.io IMAGE_NAME=test-pod-identity PYTHON_VERSION=3.9
```

Build an image:
```sh
docker build --no-cache --build-arg PYTHON_VERSION=$PYTHON_VERSION -t $REPOSITORY/$IMAGE_NAME:$PYTHON_VERSION ./managed-identity-live
```

Push it to ACR:
```sh
docker push $REPOSITORY/$IMAGE_NAME:$PYTHON_VERSION
```

## Run the tests

### Install kubectl
```sh
az aks install-cli
```

### Authenticate kubectl and helm
```sh
az aks get-credentials -g $RESOURCE_GROUP -n $AKS_NAME
```

### Run the test script
```sh
python ./pod-identity/run-test.py \
 --client-id $MANAGED_IDENTITY_CLIENT_ID \
 --resource-id $MANAGED_IDENTITY_ID \
 --vault-url https://$KEY_VAULT_NAME.vault.azure.net \
 --repository $REPOSITORY \
 --image-name $IMAGE_NAME \
 --image-tag $PYTHON_VERSION
```

Successful test output looks like this:
```
============================= test session starts ==============================
platform linux -- Python 3.9.15, pytest-7.2.0, pluggy-1.0.0 -- /usr/local/bin/python
cachedir: .pytest_cache
rootdir: /sdk/identity/azure-identity
plugins: cov-4.0.0, asyncio-0.20.2
asyncio: mode=strict
collecting ... collected 4 items

test_cloud_shell.py::test_cloud_shell_live SKIPPED (Cloud Shell MSI ...) [ 25%]
test_cloud_shell_async.py::test_cloud_shell_live SKIPPED (Cloud Shel...) [ 50%]
test_managed_identity_live.py::test_managed_identity_live PASSED         [ 75%]
test_managed_identity_live_async.py::test_managed_identity_live PASSED   [100%]

=========================== short test summary info ============================
SKIPPED [2] conftest.py:46: Cloud Shell MSI unavailable
========================= 2 passed, 2 skipped in 1.29s =========================
```

**Note**: The `run_test.py` script may hang for a long time after the tests complete as it waits
for one of the test resources (AzureAssignedIdentity) to be deleted. Feel free to Ctrl-C if
the cluster will just be deleted afterwards.

## Delete Azure resources
```sh
az group delete -n $RESOURCE_GROUP -y --no-wait
```