1
votes

I am trying to use the Azure SDK for Javascript to list all the resources within an Azure subscription. My approach has been to authenticate using the @azure/ms-rest-nodeauth package and then call ResourceManagementClient from the @azure/arm-resources package but I am having several issues.

1. App registration

I have opted to use msRestNodeAuth.loginWithServicePrincipalSecretWithAuthResponse(). I went into AzureAD and created a new app registration and then within that a secret. This gives me a clientId, a secret and a tenantId that I can supply to the function.

However, the issue I feel I will face (once I actually get my code working) is permissioning. I have no idea what permissions need to be applied to this app registration to allow it to query resources like this.

I cannot see this described in any of the docs that I've looked at.

2. ESM / CJS issues

I am running v12.16.1 of NodeJS. In order to use the ESM import syntax I am supplying the --experimental-modules flag along with es-module-specifier-resolution=node so that file extensions do not need to be supplied when importing (the package.json file also has type: "module" set). This has worked fine across many packages, but on the two packages above the imports seem have a wrapper meaning that I need to call .default in order to access the actual function:

enter image description here

For example:

import * as msRestNodeAuth from "@azure/ms-rest-nodeauth";
const res = await msRestNodeAuth.loginWithServicePrincipalSecretWithAuthResponse(_clientId, _secretValue, _tennantId);

...must become:

import * as msRestNodeAuth from "@azure/ms-rest-nodeauth";
const res = await msRestNodeAuth.default.loginWithServicePrincipalSecretWithAuthResponse(_clientId, _secretValue, _tennantId);

The code works when doing this, but my guess is that something is off with how the package has been built / how my NodeJS setup is configured. I also cannot import ResourceManagementClient from @azure/arm-resources, instead having to do this:

// This errors:
// import { ResourceManagementClient } from "@azure/arm-resources";
// ...but I can access it like:
import * as armResources from "@azure/arm-resources";

const client = new armResources.default.ResourceManagementClient();

3. Putting it all together

When I try to put it all together and get a list of resource groups, I get an error:

const res = await msRestNodeAuth.default.loginWithServicePrincipalSecretWithAuthResponse(_clientId, _secretValue, _tennantId);

const client = new armResources.default.ResourceManagementClient(res.credentials, _subscriptionId);

const resourceGroups = await client.resourceGroups.list();

The client 'XYZ123' with object id 'abc678' does not have authorization to perform action 'Microsoft.Resources/subscriptions/resourcegroups/read' over scope '/subscriptions/123213123' or the scope is invalid. If access was recently granted, please refresh your credentials.

My hope is that this is just an auth error that will resolve when issue #1 is fixed - i.e. the app registration gets the permissions it needs.

Apologies for the broad scope of this question; I am used to doing this in AWS so I am trying to get to grips with both Azure and this SDK at the same time. Any help is greatly appreciated!

1
You would need to grant Azure RBAC role to your Service Principal. Please see this link for more details: docs.microsoft.com/en-us/azure/role-based-access-control/….Gaurav Mantri

1 Answers

1
votes

If you want to list all Azure resource in one subscription, you need to assign read role at subscription level. For more details, please refer to here and here enter image description here

Regarding how to assign the role to sp, we can use PowerShell to implement it

$id=(Get-AzADServicePrincipal -DisplayName <principalName>).id
New-AzRoleAssignment -ObjectId $id `
-RoleDefinitionName Reader `
-Scope /subscriptions/<subscriptionId>