From 9f03966e01e2c52afcbc10cde803aec4e5cfbbf7 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 19 Jun 2026 18:11:01 +1000 Subject: [PATCH] [AKS] Set principalType for role assignments created by AKS commands Default the principal type to ServicePrincipal for internal AKS role assignments (service principals and managed identities), and User for the Automatic SKU cluster-admin grant to the signed-in user. Providing the principal type lets the Authorization RP skip the Entra ID existence check, avoiding PrincipalNotFound failures from replication delay for freshly created identities. --- .../azure/cli/command_modules/acs/_roleassignments.py | 8 ++++++++ .../cli/command_modules/acs/managed_cluster_decorator.py | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/azure-cli/azure/cli/command_modules/acs/_roleassignments.py b/src/azure-cli/azure/cli/command_modules/acs/_roleassignments.py index 98d6e51a2a1..3e14d631907 100644 --- a/src/azure-cli/azure/cli/command_modules/acs/_roleassignments.py +++ b/src/azure-cli/azure/cli/command_modules/acs/_roleassignments.py @@ -100,6 +100,14 @@ def add_role_assignment_executor(cmd, role, assignee, resource_group_name=None, def add_role_assignment(cmd, role, service_principal_msi_id, is_service_principal=True, delay=2, scope=None, assignee_principal_type=None): + # Every caller of add_role_assignment targets either a service principal or a managed + # identity, both of which are represented as a ServicePrincipal in Microsoft Entra ID. + # Explicitly setting the principal type lets the Authorization RP skip the Entra ID + # existence check, which avoids PrincipalNotFound failures caused by replication delay + # for freshly created identities. + if assignee_principal_type is None: + assignee_principal_type = "ServicePrincipal" + # AAD can have delays in propagating data, so sleep and retry hook = cmd.cli_ctx.get_progress_controller(True) hook.add(message="Waiting for AAD role to propagate", value=0, total_val=1.0) diff --git a/src/azure-cli/azure/cli/command_modules/acs/managed_cluster_decorator.py b/src/azure-cli/azure/cli/command_modules/acs/managed_cluster_decorator.py index 518c735df8e..df48993aaac 100644 --- a/src/azure-cli/azure/cli/command_modules/acs/managed_cluster_decorator.py +++ b/src/azure-cli/azure/cli/command_modules/acs/managed_cluster_decorator.py @@ -8356,12 +8356,16 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None: except Exception as e: # pylint: disable=broad-except logger.warning("Could not get signed in user: %s", str(e)) else: + # signed_in_user_get() calls Graph /me, which only succeeds for a delegated + # (interactive) user; service principal / managed identity logins raise GraphError + # and are handled by the except branch above. So the assignee here is always a User. self.context.external_functions.add_role_assignment_executor( # type: ignore # pylint: disable=protected-access self.cmd, "Azure Kubernetes Service RBAC Cluster Admin", user["id"], scope=cluster.id, resolve_assignee=False, + assignee_principal_type="User", ) def put_mc(self, mc: ManagedCluster) -> ManagedCluster: