So that Horizon Cloud app registration has the ability to make API calls in the pod's subscription — or in the optional external gateway subscription — and perform its VDI-related operations, a role must be assigned to it. Usually the Contributor role is used for this purpose. For organizations that prefer to avoid use of the Contributor role, they can create a custom role, and have the custom role fulfill the purpose of giving the Horizon Cloud app registration the ability to perform the required API calls.

In addition to a custom role for the Horizon Cloud app registration in the pod's subscription, if your organization prefers to adopt the approach to have a separate subscription for the pod's external Unified Access Gateway configuration and also select to have the gateway resources deployed into a specific resource group that your organization sets up for that purpose, the custom role for that gateway's subscription can have more granular, narrow-scope permissions than the custom role for the pod's subscription.

Brief Introduction to Custom Roles

The overarching concept is that Horizon Cloud needs to perform certain operations in the pod's subscription and its resource groups to successfully create and maintain the resources needed to have a pod and its gateway configurations.

As a simple example, because the pod and gateway architecture require virtual machines with NICs, Horizon Cloud needs the ability to create virtual machines and NICs in your subscription and attach those NICs to subnets in the subscription's VNet.

In Microsoft Azure, a role provides for a set of management operations that can be performed by an app registration's service principal. A management operation is a combination of the resource and action performed on that resource.

You can restrict the Horizon Cloud app registration's abilities in the pod's subscription and (optional) gateway's subscription to the minimum operations required, by following the rules described below.

Overview of the Available Use Cases

When discussing Horizon Cloud required operations in subscriptions and resource groups, there are these use cases.

Note: In the two-subscription use case, the role for the app registration in the pod's subscription must follow the same rules as needed for the single-subscription use case.
Use Case Description
A single subscription used by Horizon Cloud for pods and their external Unified Access Gateway configurations.

In this case, access must be granted to the service principal at the pod's subscription level. The role assigned to the service principal at that level must allow the actions that Horizon Cloud needs to perform in your subscription to successfully create in that subscription the required resources and operate on those resources over time. As an example, in this case, the role must provide the ability to create the default resource groups, network security groups, virtual machines, and so on.

Two subscriptions, and you want Horizon Cloud to auto-create the gateway's required resource groups and resources in the external gateway's specified subscription, same as it does in the pod's subscription.
  • One subscription specified to use for the external Unified Access Gateway configuration's resources
  • One subscription for the rest of the pod resources

When using this option, the service principal for each subscription must be granted access at the subscription level, with permissions that allow actions same as those for the single subscription use case described above.

Two subscriptions as above, but instead of having Horizon Cloud auto-create the external gateway's required resource groups and resources, you create a resource group in advance in that external gateway's specified subscription, and want Horizon Cloud to deploy the external gateway's resources into that existing resource group.

Two options for granting access to the service principal used for deploying the external gateway:

  • Grant access at the subscription level, same as in the above case.
  • Use the following combination:
    • At the subscription level, grant access using the built-in Reader role.
    • At the level of the named resource group, grant access using permissions defined in a custom role. The permissions granted at the resource-group level must provide for the operations that Horizon Cloud requires to perform in the resource group to deploy and configure the external gateway's resources there.

      In addition to the permissions on the resource group, Horizon Cloud needs the permissions to perform the following actions, depending on your deployment plans:

      • If this deployment will use subnets that you create in advance on that subscription's VNet, Horizon Cloud needs the ability to create NICs and network security groups (NSGs) on those subnets. The permissions required on the VNet that the subnet belongs to are Microsoft.Network/virtualNetworks/subnets/* and Microsoft.Network/networkSecurityGroups/*
      • If this deployment will have Horizon Cloud generate the subnets, in addition to the above Microsoft.Network/virtualNetworks/subnets/* and Microsoft.Network/networkSecurityGroups/* permissions, Horizon Cloud needs the ability to create the subnets. The permission required on the VNet is Microsoft.Network/virtualNetworks/write
      • If your external gateway deployment will specify using a public IP address, Horizon Cloud needs the ability to create public IP addresses in the named resource group. The permission required on the named resource group is Microsoft.Network/publicIPAddresses
When your VNet has custom routes. Microsoft Azure Cloud has a feature called custom routes. If your VNet has custom routes, a permission is needed in addition to all of the ones for the above use cases: Microsoft.Network/routeTables/join/action.

When Using a Single Subscription for the Pod and Its Gateway Configurations or Using a Separate Subscription for the External Unified Access Gateway Configuration with Permissions Set at the Subscription Level

For these use cases, the permissions are assigned at the subscription level. The custom role must permit the operations in the following table. The * (wild card character) grants access to all operations that match the string within the listed operation.

Table 1. Microsoft Azure Resource Operations that Must Be Permitted in the Custom Role When Assigning Permissions at the Subscription Level
Operation Description in the Microsoft Azure Documentation
Microsoft.Authorization/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftauthorization
Microsoft.Compute/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/availabilitySets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/disks/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/images/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/locations/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/snapshots/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/virtualMachines/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/virtualMachineScaleSets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.DBforPostgreSQL/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftdbforpostgresql
Microsoft.KeyVault/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkeyvault
Microsoft.KeyVault/vaults/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkeyvault
Microsoft.KeyVault/vaults/secrets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkeyvault
Microsoft.Network/loadBalancers/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/networkInterfaces/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/networkSecurityGroups/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/publicIPAddresses/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/write https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/checkIpAddressAvailability/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/subnets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.ResourceHealth/availabilityStatuses/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftresourcehealth
Microsoft.Resources/subscriptions/resourceGroups/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftresources
Microsoft.Resources/deployments/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftresources
Microsoft.Storage/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftstorage
Microsoft.Storage/storageAccounts/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftstorage
Microsoft.Compute/galleries/read
Microsoft.Compute/galleries/write
Microsoft.Compute/galleries/delete
Microsoft.Compute/galleries/images/*
Microsoft.Compute/galleries/images/versions/*
https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/read
Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/write
https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftmarketplaceordering

The following JSON code block is an example to illustrate what a custom role definition named Horizon Cloud Pod might look like when it has the set of preceding operations. The ID is the unique ID of the custom role. When Azure PowerShell or Azure CLI is used to create a custom role, this ID is automatically generated. For the variable mysubscriptionId1, substitute the ID of the subscription in which the custom role will be used — the pod's subscription or the optional gateway subscription.

Table 2. Sample JSON for a Role Permitting the Horizon Cloud Required Operations When Assigning Permissions at the Subscription Level
{
"Name": "Horizon Cloud Pod",
"Id": "uuid",
"IsCustom": true,
"Description": "Minimum set of Horizon Cloud pod required operations",
"Actions": [
  "Microsoft.Authorization/*/read"
  "Microsoft.Compute/*/read"
  "Microsoft.Compute/availabilitySets/*"
  "Microsoft.Compute/disks/*"
  "Microsoft.Compute/images/*"
  "Microsoft.Compute/locations/*"
  "Microsoft.Compute/virtualMachines/*"
  "Microsoft.Compute/virtualMachineScaleSets/*"
  "Microsoft.Compute/snapshots/*"
  "Microsoft.DBforPostgreSQL/*"
  "Microsoft.KeyVault/*/read"
  "Microsoft.KeyVault/vaults/*"
  "Microsoft.KeyVault/vaults/secrets/*"
  "Microsoft.Network/loadBalancers/*"
  "Microsoft.Network/networkInterfaces/*"
  "Microsoft.Network/networkSecurityGroups/*"
  "Microsoft.Network/publicIPAddresses/*"
  "Microsoft.Network/virtualNetworks/read"
  "Microsoft.Network/virtualNetworks/write"
  "Microsoft.Network/virtualNetworks/checkIpAddressAvailability/read"
  "Microsoft.Network/virtualNetworks/subnets/*"
  "Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read"
  "Microsoft.Resources/subscriptions/resourceGroups/*"
  "Microsoft.ResourceHealth/availabilityStatuses/read"
  "Microsoft.Resources/deployments/*"
  "Microsoft.Storage/*/read"
  "Microsoft.Storage/storageAccounts/*"
  "Microsoft.Compute/galleries/read"
  "Microsoft.Compute/galleries/write"
  "Microsoft.Compute/galleries/delete"
  "Microsoft.Compute/galleries/images/*"
  "Microsoft.Compute/galleries/images/versions/*"
  "Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/read"
  "Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/write"
  ],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
  "/subscriptions/mysubscriptionId1"
  ]
}

When Custom Routes are in Your VNet and Its Subnets

Microsoft Azure cloud has a feature called custom routes.

If you have such routes added to your VNet and its subnets, this additional permission is needed.

Table 3. Microsoft Azure Resource Operation that Must Be Permitted when Your VNet Has Custom Routes
Operation Description in the Microsoft Azure Documentation
Microsoft.Network/routeTables/join/action https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork

When Using a Separate Subscription for the External Unified Access Gateway Configuration, Deploying into a Custom Resource Group, with Reader Role at the Subscription Level and Additional Required Permissions Assigned at Granular Levels

For this use case, at the subscription level of the external gateway's subscription, your organization can use the built-in Reader role for Horizon Cloud app registration to use, plus a custom role at the level of the named resource group.

Your organization would create a custom role which specifies the permissions in the following table. That custom role would then be assigned to Horizon Cloud app registration to operate with the specifically named resource group in the external gateway's subscription. You or your organization would pre-create that named resource group in the subscription in which you are deploying the external gateway.

Some specific permissions on subnets and on the VNet are also required, depending on your planned deployment options:

  • If this external gateway deployment will use subnets that are created in advance, Horizon Cloud needs the ability to create NICs and network security groups (NSGs) on those subnets. The permissions required on the VNet that the subnet belongs to are Microsoft.Network/virtualNetworks/subnets/* and Microsoft.Network/networkSecurityGroups/*.
  • If this external gateway deployment will have Horizon Cloud generate the subnets, in addition to the above Microsoft.Network/virtualNetworks/subnets/* and Microsoft.Network/networkSecurityGroups/* permissions, Horizon Cloud needs the ability to create the subnets. The permission required on the subscription's VNet is Microsoft.Network/virtualNetworks/write
  • If your deployment will specify using a public IP address for the external gateway configuration, Horizon Cloud needs the ability to create public IP addresses in the named resource group. The permission required on the named resource group is Microsoft.Network/publicIPAddresses

The following permitted operations are required in the named resource group. The * (wild card character) grants access to all operations that match the string within the listed resource provider operation.

Table 4. Microsoft Azure Resource Operations that Must Be Permitted on the Specified Resource Group
Operation Description in the Microsoft Azure Documentation
Microsoft.Authorization/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftauthorization
Microsoft.Compute/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/availabilitySets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/disks/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/images/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/locations/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/snapshots/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/virtualMachines/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.Compute/virtualMachineScaleSets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftcompute
Microsoft.DBforPostgreSQL/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftdbforpostgresql
Microsoft.KeyVault/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkeyvault
Microsoft.KeyVault/vaults/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkeyvault
Microsoft.KeyVault/vaults/secrets/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkeyvault
Microsoft.Network/loadBalancers/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/networkInterfaces/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/publicIPAddresses/*, if your deployment will specify using a public IP address for the external gateway deployment. https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/checkIpAddressAvailability/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork
Microsoft.ResourceHealth/availabilityStatuses/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftresourcehealth
Microsoft.Resources/subscriptions/resourceGroups/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftresources
Microsoft.Resources/deployments/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftresources
Microsoft.Storage/*/read https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftstorage
Microsoft.Storage/storageAccounts/* https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftstorage
Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/read
Microsoft.MarketplaceOrdering/offertypes/publishers/offers/plans/agreements/write
https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftmarketplaceordering