az aks create|update --attach-acr makes undue graph api calls that results in `Could not create a role assignment for ACR. Are you an Owner on this subscription?`
- Dominant language
- Python
- Stars
- 4.6k
- Forks
- 3.5k
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 60
Description
**Describe the bug**
Running with a managed identity which is **Contributor** on the resource group, **Owner** on the ACR repo, and a cluster with managed identities enabled:
```
az aks update -g $RESOURCE_GROUP -n $CLUSTER_NAME --attach-acr $ACRNAME
```
Results in `Could not create a role assignment for ACR. Are you an Owner on this subscription?`. Though this is [documented as an expected behavior](https://github.com/MicrosoftDocs/azure-docs/issues/64083) of ACR, it is not. It is a bug of Azure CLI that makes a useless call to Graph API to get an information it already has.
Can be reproduced at creation too.
**To Reproduce**
Follow the information given before.
**Expected behavior**
The call should succeed in giving the role assignment to the cluster. Proof by workaround, since the expected result can be achieved by doing this:
```
role_id=$(az role definition list \
--scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACRNAME" \
--name AcrPull \
--query "[0].id" -o tsv)
object_id=$(az aks show \
-g $RESOURCE_GROUP \
-n $CLUSTER_NAME \
--query "identityProfile.kubeletidentity.objectId" -o tsv)
az role assignment create \
--scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACRNAME" \
--role "$role_id" \
--assignee-object-id "$object_id" \
--assignee-principal-type ServicePrincipal
```
Which is a direct proof that the limitation is on Azure CLI side and not in ACR product.
**Environment summary**
`azure-cli` version `2.25.0-1` installed with official rpm.
Running in a machine with image `OpenLogic:CentOS:7_8-gen2`.
**Additional context**
This happens because the code path that makes the role assignment does not care whether the identity is a Service Principal or a Managed Identity.
We can see it here in `command_modules/acs/custom.py`:
```
def _ensure_aks_acr_role_assignment(cli_ctx,
client_id,
registry_id,
detach=False):
if detach:
if not _delete_role_assignments(cli_ctx,
'acrpull',
client_id,
scope=registry_id):
raise CLIError('Could not delete role assignments for ACR. '
'Are you an Owner on this subscription?')
return _add_role_assignment(cli_ctx, role, service_principal_msi_id, is_service_principal=True, delay=2, scope=None)
if not _add_role_assignment(cli_ctx,
'acrpull',
client_id,
scope=registry_id):
raise CLIError('Could not create a role assignment for ACR. '
'Are you an Owner on this subscription?')
return
```
The call to `_add_role_assignment` let the parameter `is_service_principal=True`, which trickles down to a call to `_resolve_object_id` , which makes a call to the Graph API. Then failure ensues, since the Managed Identity has not been granted any Graph API authorizations.
But this call is not required since the AKS api already provides this `object_id`. Therefore, the Graph API call should be avoided and the role assignment can succeed.
Contributor guide
Assessment
This issue has not been assessed yet.