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:
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)?
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:
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:
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:
In my case, I assigned "Virtual Machine Contributor" role to service principal under Azure VM:
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:
To confirm that, I checked the same in Portal where VM started successfully as below:
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.