Contributor 角色通常用于启用 Horizon Cloud 应用程序注册过程,以便在 Microsoft Azure 订阅中进行 API 调用。如果您希望避免使用 Contributor 角色,则可以创建自定义角色以实现此目的。自定义角色具有某些必需权限和可选权限,在创建服务主体时必须注意这些权限。

要创建自定义角色,请使用 Azure PowerShell 或 Azure CLI 等工具,创建一个至少包含本主题中所列必需权限的自定义角色定义。请参阅下面的 JSON 示例。有关此页面中列出的特定 Microsoft Azure 权限的详细信息,请参阅 Azure 资源提供程序操作

必需权限

表 1. 在订阅级别分配权限时必须在自定义角色中允许的 Microsoft Azure 资源操作
操作
Microsoft.Authorization/*/read
Microsoft.Compute/*/read
Microsoft.Compute/availabilitySets/*
Microsoft.Compute/disks/*
Microsoft.Compute/galleries/read
Microsoft.Compute/galleries/write
Microsoft.Compute/galleries/delete
Microsoft.Compute/galleries/images/*
Microsoft.Compute/galleries/images/versions/*
Microsoft.Compute/images/*
Microsoft.Compute/locations/*
Microsoft.Compute/snapshots/*
Microsoft.Compute/virtualMachines/*
Microsoft.Compute/virtualMachineScaleSets/*
Microsoft.ContainerService/managedClusters/delete
Microsoft.ContainerService/managedClusters/read
Microsoft.ContainerService/managedClusters/write
Microsoft.ContainerService/managedClusters/commandResults/read
Microsoft.ContainerService/managedClusters/runcommand/action
Microsoft.ContainerService/managedClusters/upgradeProfiles/read
Microsoft.ManagedIdentity/userAssignedIdentities/*/assign/action
Microsoft.ManagedIdentity/userAssignedIdentities/*/read
Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/read
Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/write
Microsoft.Network/loadBalancers/*
Microsoft.Network/networkInterfaces/*
Microsoft.Network/networkSecurityGroups/*
Microsoft.Network/virtualNetworks/read
Microsoft.Network/virtualNetworks/write
Microsoft.Network/virtualNetworks/checkIpAddressAvailability/read
Microsoft.Network/virtualNetworks/subnets/*
Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read
Microsoft.ResourceGraph/*
Microsoft.Resources/deployments/*
Microsoft.Resources/subscriptions/read
Microsoft.Resources/subscriptions/resourceGroups/*
Microsoft.ResourceHealth/availabilityStatuses/read
Microsoft.Storage/*/read
Microsoft.Storage/storageAccounts/*

如果您打算使用 App Volumes,请确保您在订阅级别配置了表中列出的权限。有关这些权限的更多信息,请参阅App Volumes 应用程序存储帐户的 Azure 专用端点

操作
Microsoft.Network/locations/availablePrivateEndpointTypes/read
Microsoft.Network/privateEndpoints/read
Microsoft.Network/privateEndpoints/write
Microsoft.Network/privateEndpoints/delete
Microsoft.Network/virtualNetworks/read
Microsoft.Network/virtualNetworks/subnets/read
Microsoft.Network/virtualNetworks/subnets/write
Microsoft.Network/virtualNetworks/subnets/join/action
Microsoft.Resources/deployments/*
Microsoft.Resources/subscriptions/read
Microsoft.Resources/subscriptions/resourceGroups/read

可选权限

在 Microsoft Azure 中部署 Horizon Edge,以下权限不是必需权限。但是,如果不包含这些可选权限,Horizon Universal Console 中依赖这些权限的功能将无法正常工作。

表 2. 在订阅级别分配权限时在自定义角色中可选的 Microsoft Azure 资源操作
操作
Microsoft.KeyVault/*/read
Microsoft.KeyVault/vaults/*
Microsoft.KeyVault/vaults/secrets/*
池虚拟机的磁盘加密需要密钥文件库权限。
Microsoft.Network/natGateways/join/action
如果在创建 Horizon Edge 时选择了 Azure 专用链路连接类型,并且管理子网已关联 NAT 网关,则需要此权限。需要此权限才能创建专用端点资源。
Microsoft.Network/natGateways/read
如果选择“NAT 网关”作为 Horizon Edge 的集群出站类型,则需要此权限才能验证管理子网的 NAT 网关(如果存在)是否已正确配置。
Microsoft.Network/privateEndpoints/write
Microsoft.Network/privateEndpoints/read
需要具有专用端点权限才能使用 Azure 专用链路部署 Horizon Edge。
Microsoft.Network/publicIPAddresses/* 需要公用 IP 权限才能在具有公用 IP 地址的负载均衡器后面部署具有 Unified Access Gateway 实例的 Horizon Edge 实例。另外,需要此权限才能部署公用 IP 地址并将其添加到映像。
Microsoft.Network/routeTables/join/action
如果在创建 Horizon Edge 时选择了 Azure 专用链路连接类型,并且管理子网已附加路由表,则需要此权限。需要此权限才能创建专用端点资源。
Microsoft.Network/routeTables/read
如果为 Horizon Edge 选择的集群出站类型为“用户定义的路由”,则需要此权限。需要此权限才能验证管理子网的关联路由表,以确保正确配置默认路由。
注: 在删除已加入 Microsoft Entra ID 的池或虚拟机时,服务主体应具有从 Microsoft Entra ID 中删除设备条目的权限。

权限相关内容如下:

范围:https://graph.microsoft.com/

权限:Device.ReadWrite.All Read and write devices

管理员同意:Yes

可以通过导航到以下位置来授予权限:

订阅 > Azure Active Directory > 应用程序注册 > 选择需要授予权限的应用程序 > API 权限 > 选择 Microsoft GRAPH > 选择 Device.ReadWriteAll

Microsoft Azure 自定义角色 JSON 示例

以下 JSON 代码块是一个示例,说明了名为 Horizon Cloud 自定义角色 - Titan 的自定义角色定义在具有一组上述必需操作和可选操作时的外观。ID 是自定义角色的唯一 ID。使用 Azure PowerShell 或 Azure CLI 创建自定义角色时,该过程会自动生成此 ID。对于变量 my_subscription_ID,请替换将在其中使用自定义角色的订阅的 ID。

assignableScopes 部分中,您可以使用多个订阅 ID“/subscriptions/my_subscription_ID”,以允许在多个订阅中使用自定义角色。

表 3. 在订阅级别分配权限时允许执行 Horizon Cloud 所需操作的角色的示例 JSON
{
    “id”: “uuid”,
    “properties”: {
        “roleName”: “Horizon Cloud Custom Role - Titan”,
        “description”: “All permissions required for deployment and operation of a Horizon Edge in Azure”,
        “assignableScopes”: [
              “/subscriptions/my_subscription_ID”
        ],
        “permissions”: [
            {
                “actions”: [
                    “Microsoft.Authorization/*/read”,
                    “Microsoft.Compute/*/read”,
                    “Microsoft.Compute/availabilitySets/*“,
                    “Microsoft.Compute/disks/*“,
                    “Microsoft.Compute/galleries/read”,
                    “Microsoft.Compute/galleries/write”,
                    “Microsoft.Compute/galleries/delete”,
                    “Microsoft.Compute/galleries/images/*”,
                    “Microsoft.Compute/galleries/images/versions/*”,
                    “Microsoft.Compute/images/*”,
                    “Microsoft.Compute/locations/*”,
                    “Microsoft.Compute/snapshots/*”,
                    “Microsoft.ContainerService/managedClusters/delete”,
                    “Microsoft.ContainerService/managedClusters/read”,
                    “Microsoft.ContainerService/managedClusters/write”,        
                    “Microsoft.ContainerService/managedClusters/commandResults/read”,
                    “Microsoft.ContainerService/managedClusters/runcommand/action”,
                    “Microsoft.ContainerService/managedClusters/upgradeProfiles/read”,
                    “Microsoft.ManagedIdentity/userAssignedIdentities/*/assign/action”,
                    “Microsoft.ManagedIdentity/userAssignedIdentities/*/read”,
                    “Microsoft.Compute/virtualMachines/*”,
                    “Microsoft.Compute/virtualMachineScaleSets/*”,
                    “Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/read”,
                    “Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/write”,
                    “Microsoft.Network/loadBalancers/*”,           
                    “Microsoft.Network/networkInterfaces/*”,
                    “Microsoft.Network/networkSecurityGroups/*”,
                    “Microsoft.Network/virtualNetworks/read”,
                    “Microsoft.Network/virtualNetworks/write”,
                    “Microsoft.Network/virtualNetworks/checkIpAddressAvailability/read”,
                    “Microsoft.Network/virtualNetworks/subnets/*”,
                    “Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read”,
                    “Microsoft.ResourceGraph/*”,
                    “Microsoft.Resources/deployments/*”,
                    “Microsoft.Resources/subscriptions/read”,
                    “Microsoft.Resources/subscriptions/resourceGroups/*”,
                    “Microsoft.ResourceHealth/availabilityStatuses/read”,
                    “Microsoft.Storage/*/read”,
                    “Microsoft.Storage/storageAccounts/*”,
                    “Microsoft.KeyVault/*/read”,
                    “Microsoft.KeyVault/vaults/*”,
                    “Microsoft.KeyVault/vaults/secrets/*”,
                    “Microsoft.Network/natGateways/join/action”,
                    “Microsoft.Network/natGateways/read”,
                    “Microsoft.Network/privateEndpoints/write”,
                    “Microsoft.Network/privateEndpoints/read”,
                    “Microsoft.Network/publicIPAddresses/*”,
                    “Microsoft.Network/routeTables/join/action",
                    "Microsoft.Network/routeTables/read"
                ],
                “notActions”: [],
                “dataActions”: [],
                “notDataActions”: []
            }
        ]
    }
}