How to grant RBAC permissions on resource group in a different subscription using ARM template

Lately, I don’t get to work on something worth blogging about. Usually it’s either something boring (like compliance) or internal (and hence confidential). But today was a good exception: after my service’s infrastructure has migrated its Key Vaults from access policies to RBAC, I needed to update the ARM template accordingly.

Surprisingly, I was able to find a quickstart tutorial about how to grant the permissions on a resources group. In my case, the caveat is that the target resource group is located in a different subscription. So I had to combine two approaches, the another one being described in this article.

Here’s the resulting template:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string"
    },
    "subscriptionId": {
      "type": "string"
    },
    "resourceGroup": {
      "type": "string"
    },
    "principalId": {
      "type": "string"
    }
  },
  "variables": {
    "contributorGuid": "b24988ac-6180-42a0-ab88-20f7382dd24c", // see https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#privileged
    "contributorResourceId": "[resourceId('Microsoft.Authorization/roleDefinitions/', variables('contributorGuid'))]",
  },
  "resources": [
    {
      "name": "[format('Permissions-ResourceGroup-{0}', parameters('principalId')]",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2024-11-01",
      "subscriptionId": "[parameters('subscriptionId')]",
      "resourceGroup": "[parameters('resourceGroupName')]",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "name": "[guid(subscriptionResourceId(parameters('subscriptionId'), 'Microsoft.Resources/resourceGroups', parameters('resourceGroupName')), parameters('principalId')], variables('contributorResourceId')]",
              "type": "Microsoft.Authorization/roleAssignments",
              "apiVersion": "2022-04-01",
              "location": "[parameters('location')]",
              "properties": {
                "roleDefinitionId": "[variables('contributorResourceId')]",
                "principalId": "[parameters('principalId')]",
                "principalType": "ServicePrincipal"
              }
            }
          ]
        }
      }
    }
  ]
}

Happy deployment, folks!

This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{63EBCF4C-B326-4539-A3CB-B50746D6C323}’ failed

If you’re running a code like this:

builder.Services.TryAddSingleton<FabricClient>();

In a Service Fabric application locally and getting an error:

System.InvalidCastException:
Unable to cast COM object of type ‘System.__ComObject’ to interface type ‘IInternalFabricClusterManagementClient2’.
This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{63EBCF4C-B326-4539-A3CB-B50746D6C323}’ failed due to the following error: No such interface supported (0x80004002 (E_NOINTERFACE)).’

First what you need to do is to convert it to something like this:

builder.Services.TryAddSingleton<FabricClient>(_ => new FabricClient());

The exception’s call site would be located in the user’s code, not the framework’s so you could see the actual exception and its stack trace.

The exception likely occurs because the NuGet package referenced from the Service Fabric service project, e.g.:

<PackageReference Include="Microsoft.ServiceFabric" Version="9.1.1390" />

Has diverged from the Service Fabric SDK installed locally, e.g:

You need to install the matching SDK version from here.

Carnation Anapa Winery, vol 4, day 23: racking (cont’d)

I racked the bucket with Petit Verdot and got about 3 gallons. Now it seats half-empty and I need to decide what to do with it: pour into three 1-gallon carboys or top off with similar retail wine or something else.

I also racked the carboy with Malbec and added 5 French oak spheres. But first I soaked them in a bowl of boiled water to kill any germs.