skip to Main Content

I have an Azure subscription and an image I created.

I wrote some typescript code to a monitoring webpage that will allow users from the organization to spawn more instances of this image (first stage).

I’m using the default active directory, and have created a new user "admin" that has both "Application Administrator" and "Cloud Application Administrator" (does it really need both?).

I’m having an issue with the authentication.
The error I’m getting is:

Error creating VM: RestError: The client '<clientID>' with object id '<clientID>' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/write' over scope '/subscriptions/<subscriptionID>/resourceGroups/Azure-test_group/providers/Microsoft.Compute/virtualMachines/myVM' or the scope is invalid. If access was recently granted, please refresh your credentials. 
 {
  "name": "RestError",
  "code": "AuthorizationFailed",
  "statusCode": 403,
  "request": {
    "url": "https://management.azure.com/subscriptions/<SubscriptionID>/resourceGroups/Azure-test_group/providers/Microsoft.Compute/virtualMachines/myVM?api-version=2023-03-01",
    "headers": {
      "content-type": "application/json",
      "accept": "application/json",
      "accept-encoding": "gzip,deflate",
      "user-agent": "azsdk-js-arm-compute/21.1.0 core-rest-pipeline/1.12.0 Node/v16.17.0 OS/(arm64-Darwin-21.6.0)",
      "x-ms-client-request-id": "<id>",
      "authorization": "REDACTED",
      "content-length": "324"
    },
    "method": "PUT",
    "timeout": 0,
    "disableKeepAlive": false,
    "streamResponseStatusCodes": {},
    "withCredentials": false,
    "requestId": "<Id>",
    "allowInsecureConnection": false,
    "enableBrowserStreams": false
  },
  "details": {
    "error": {
      "code": "AuthorizationFailed",
      "message": "The client '<clientID>' with object id '<clientID>' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/write' over scope '/subscriptions/<SubscriptionID>/resourceGroups/Azure-test_group/providers/Microsoft.Compute/virtualMachines/myVM' or the scope is invalid. If access was recently granted, please refresh your credentials."
    }
  },
  "message": "The client '<clientID>' with object id '<clientID>' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/write' over scope '/subscriptions/<SubscriptionID>/resourceGroups/Azure-test_group/providers/Microsoft.Compute/virtualMachines/myVM' or the scope is invalid. If access was recently granted, please refresh your credentials."
}

my code files look as follows:

1.

// pages/api/azure-test/index.tsx

import { useState } from 'react';

interface AzureVm {
    InstanceId: string;
    PublicIpAddress: string | null;
}

const TestPage = () => {
    const [isLoading, setIsLoading] = useState(false);
    const [vms, setVms] = useState<AzureVm[]>([]);
    // Function to handle creating a new Azure VM
    const handleCreateInstance = async () => {
        setIsLoading(true);

        try {
            const response = await fetch('/api/azure-create-instance', { method: 'POST' });
            if (response.ok) {
                console.log('VM created successfully!');
                // fetchVms(); // Refresh the vm list after creation
            } else {
                console.error('Failed to create vm.');
            }
        } catch (error) {
            console.error('An error occurred:', error);
        } finally {
            setIsLoading(false);
        }
    };
    return (
        <div>
            <h1>Test Page</h1>
            <button onClick={handleCreateInstance} disabled={isLoading}>
                {isLoading ? 'Creating VM...' : 'Create VM'}
            </button>
            <table>
                <thead>
                    <tr>
                        <th>VM ID</th>
                        <th>Public IP Address</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {vms.map((vm) => (
                        <tr key={vm.InstanceId}>
                            <td>{vm.InstanceId}</td>
                            <td>{vm.PublicIpAddress || 'N/A'}</td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
};

export default TestPage;
// pages/api/azure-create-instances.ts

import { ComputeManagementClient, VirtualMachine } from '@azure/arm-compute';
import { DefaultAzureCredential } from '@azure/identity';

const subscriptionId = process.env.AZURE_SUBSCRIPTION_ID!;
// console.log('subscriptionId: ', subscriptionId);
const resourceGroupName = 'Azure-test_group'; // Replace with your resource group name
const vmName = 'myVM'; // Replace with your desired VM name
const location = 'westeurope'; // Replace with your desired location
const vmSize = 'Standard_DS1_v2'; // Replace with your desired VM size

const createVM = async () => {
    try {
        // Authenticate using DefaultAzureCredential
        const creds = new DefaultAzureCredential();
        // console.log(creds);
        const computeClient = new ComputeManagementClient(creds, subscriptionId);

        // Define VM parameters
        const vmParams: VirtualMachine = {
            location,
            hardwareProfile: {
                vmSize,
            },
            storageProfile: {
                imageReference: {
                    publisher: 'Canonical',
                    offer: 'UbuntuServer',
                    sku: '18.04-LTS',
                    version: 'latest',
                },
            },
            osProfile: {
                computerName: vmName,
                adminUsername: 'myAdmin', // Replace with your desired admin username
                adminPassword: 'myPassword123!', // Replace with your desired admin password
            },
            networkProfile: {
                // Network configuration
            },
            // Other VM configurations
        };

        // Create VM
        const result = await computeClient.virtualMachines.beginCreateOrUpdate(resourceGroupName, vmName, vmParams);
        console.log('VM created:', result);
    } catch (err) {
        console.error('Error creating VM:', err);
    }
};

createVM();

my .env file has the following Ids: AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID But I think the authentication still fails.

I am not sure if it is something I should change in the Azure portal, or in the code.
Important to note, so far I only gave the secret ID (AZURE_CLIENT_SECRET) but still did not use anywhere the secret "value".

any help / guidance would be appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    [adding role assignment1

    Above is a screen shot of adding the role assignment, below is me checking that the roles exist.

    enter image description here


  2. I assigned the user "Application Administrator" and "Cloud Application Administrator" role and when I tried to create the VM, I got the same error:

    enter image description here

    The client ” with object id ” does not have authorization to perform action ‘Microsoft.Compute/virtualMachines/write’ over scope
    ‘/subscriptions//resourceGroups/Azure-test_group/providers/Microsoft.Compute/virtualMachines/myVM’ or the scope is invalid. If access was recently granted, please refresh your credentials.

    The error usually occurs if the user doesn’t have sufficient permissions to perform the action.

    Note that: To create VM the user must have Virtual Machine Contributor role assigned in the subscription level.

    The "Application Administrator**" and "Cloud Application Administrator" doesn’t include Microsoft.Compute/virtualMachines/write permission which is needed to create VM.

    The Virtual Machine Contributor role have the permission:

    enter image description here

    To resolve the error, assign Virtual Machine Contributor role to the user like below:

    enter image description here

    After assigning the role, you will be able to create the VMs.

    Reference:

    Azure built-in roles – Azure RBAC

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search