node.jsazureazure-active-directoryazure-service-principal

Azure nodejs SDK list resource groups, empty result


I am trying to use the node SDK to list resource groups, I managed to get it to work with Interactive login but not with a service principal.

const {
  ClientSecretCredential,
  DefaultAzureCredential,
} = require("@azure/identity");
const ComputeManagementClient = require('azure-arm-compute')
const { ResourceManagementClient } = require("@azure/arm-resources");
var msRestAzure = require('ms-rest-azure');

const tenantId =
  process.env["AZURE_TENANT_ID"] || "XXXXXX";
const clientId =
  process.env["AZURE_CLIENT_ID"] || "XXXXX";
const secret =
  process.env["AZURE_CLIENT_SECRET"] || "XXXXXX";
const sub = 'XXXXXX';

async function listResourceGroups(){
  msRestAzure.loginWithServicePrincipalSecret(clientId, secret, tenantId, async function (err, credentials) { // KO
 //msRestAzure.interactiveLogin(async function (err, credentials) { // OK
    const resourceClient = new ResourceManagementClient(credentials, sub);
    let resourceGroups = await resourceClient.resourceGroups.list();
    console.log(resourceGroups)
    resourceGroups.forEach(element => {console.log(element)})
  })
}
listResourceGroups()

I get the following result, which looks like an empty list:

{
  next: [Function: next],
  byPage: [Function: byPage],
  [Symbol(Symbol.asyncIterator)]: [Function: [Symbol.asyncIterator]]
}
/temp/azure/resgroups.js:34
    resourceGroups.forEach(element => {console.log(element)})
                   ^

TypeError: resourceGroups.forEach is not a function
    at /temp/azure/resgroups.js:34:20
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

The service principal was created with Reader permissions.

What am I missing ?


Solution

  • I have one service principal with Reader role under subscription like this:

    enter image description here

    In my case, I used below modified code and got the response with list of resource groups successfully:

    const { ResourceManagementClient } = require("@azure/arm-resources");
    const { ClientSecretCredential } = require("@azure/identity");
    
    const tenantId = "tenantId";
    const clientId = "appId";
    const clientSecret = "secret";
    const subscriptionId = "subId";
    
    async function listResourceGroups() {
        try {
            const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
            const resourceClient = new ResourceManagementClient(credential, subscriptionId);
            const resourceGroups = await resourceClient.resourceGroups.list();
            console.log("List of Resource Groups:");
            for await (const group of resourceGroups) {
                console.log(`- ${group.name}`);
            }
        } catch (error) {
            console.error("Error listing resource groups:", error.message);
        }
    }
    
    listResourceGroups();
    

    Response:

    enter image description here