David Rogers
David Rogers

Reputation: 2653

Systematic Way to Identify Through Azure UI Required "App Registration" API Permission

Ok, I have this code (snippet) that is responsible for starting a VM:

var azure = Azure
    .Configure()
    .Authenticate(credentials)
    .WithSubscription(data.SubscriptionId);

var vm = await azure.VirtualMachines.GetByResourceGroupAsync("YourResourceGroupName", data.VmName);

if (vm == null)
{
    return new NotFoundObjectResult($"VM with name {data.VmName} not found");
}

await vm.StartAsync();

I run it from a Azure function, it fails:

System.Private.CoreLib: Exception while executing function: StartVM. Microsoft.Azure.Management.Compute.Fluent: The client 'XXX' with object id 'XXX' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/read' over scope '/subscriptions/XXX/resourceGroups/YourResourceGroupName/providers/Microsoft.Compute/virtualMachines/XXX' or the scope is invalid. If access was recently granted, please refresh your credentials.

Fair... as I haven't added that permission to my Azure "App Registration", so I go there:

enter image description here

An honestly, I have not idea where to find this, I've clicked through most of them. I've faced this issue several times so my question is, is there a easy way on the Azure UI or programmatically to go from the permission path stated in the error to adding it in the UI?

Microsoft.Compute/virtualMachines/read

Corresponds to which category in the UI and which subcategory, and how do I determine that in a generic sense in the future (with the next permissions error)?

Upvotes: 0

Views: 72

Answers (1)

Sridevi
Sridevi

Reputation: 22597

The error occurs if the service principal does not have proper permissions or roles to perform the operation.

I have one Azure VM named srivm which is in "Stopped" state as below:

enter image description here

Initially, I too got same error when I tried to start the VM by authenticating with service principal not having any Azure RBAC roles under VM:

enter image description here

To find which Azure RBAC role has 'Microsoft.Compute/virtualMachines/read or other permissions, you can refer this Azure built-in roles for Compute document:

enter image description here

In my case, I assigned "Virtual Machine Contributor" role to service principal under Azure VM:

enter image description here

After assigning the role, I ran below sample code and got response like this:

using Azure.Core;
using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;

namespace StartVM
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var data = new StartVmData
            {
                SubscriptionId = "subId",
                ResourceGroupName = "rgname",
                VmName = "vmname",
                ClientId = "appId",
                ClientSecret = "secret",
                TenantId = "tenantId"
            };

            await StartVirtualMachineAsync(data);
        }

        public static async Task StartVirtualMachineAsync(StartVmData data)
        {
            try
            {
                var credential = new ClientSecretCredential(data.TenantId, data.ClientId, data.ClientSecret);
                var armClient = new ArmClient(credential, data.SubscriptionId);
                var resourceGroup = armClient.GetResourceGroupResource(new ResourceIdentifier($"/subscriptions/{data.SubscriptionId}/resourceGroups/{data.ResourceGroupName}"));
                var vm = await resourceGroup.GetVirtualMachineAsync(data.VmName);

                if (vm == null)
                {
                    Console.WriteLine($"VM with name {data.VmName} not found.");
                    return;
                }

                Console.WriteLine($"Starting VM {data.VmName}...");
                var operation = await vm.Value.PowerOnAsync(WaitUntil.Completed);
                Console.WriteLine($"VM {data.VmName} has been started successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error occurred: {ex.Message}");
            }
        }
    }

    public class StartVmData
    {
        public string SubscriptionId { get; set; } = string.Empty;
        public string ResourceGroupName { get; set; } = string.Empty;
        public string VmName { get; set; } = string.Empty;
        public string ClientId { get; set; } = string.Empty;
        public string ClientSecret { get; set; } = string.Empty;
        public string TenantId { get; set; } = string.Empty;
    }
}

Response:

enter image description here

To confirm that, I checked the same in Portal where VM started successfully as below:

enter image description here

Note that, API permissions are required when you are working with tenant level Microsoft APIs like Microsoft Graph, SharePoint, Power BI etc...

While working with subscription-level Azure resources, you must assign Azure RBAC roles to the user or service principal under scopes like subscription, resource group or resource level.

Upvotes: 1

Related Questions