简体   繁体   中英

Access azure billing API

I would like to create a dashboard with graphs about costs of my azure resources (as detailed as possible). Meaning, a list of monthly invoices is not enough (but I would already be very happy if I a could achieve that!!)

Anyway, the first thing I noticed is that if you find an example the endpoint urls look like this

 https://management.azure.com/subscriptions/${subscriptionId}/resourcegroups?api-version=2016-09-01

Check the end of the url 2016-09-01 , doesn't look very up2date. This medium post was the best article I could find, but it also uses these urls. Furthermore, I was not able to follow the steps described, first it uses postman to retrieve an access_token (not very useful for me because I need it automated) and second, somewhere in the middle an access_token is retrieved but never used.

So, I found a npm packages like [azure-arm-billing][2] from which I was able to write the following program (mostly copy-paste):

const msRestAzure = require('ms-rest-azure');
const BillingManagement = require('azure-arm-billing')

const clientId = process.env['CLIENT_ID'];
const secret = process.env['APPLICATION_SECRET'];
const domain = process.env['DOMAIN']; 
const subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];

// Retrieve access_token
const app = new msRestAzure.ApplicationTokenCredentials(clientId, domain, secret);
app.getToken((err, token) => {
    console.log(token.accessToken);
});

// =======
msRestAzure
  .interactiveLogin( { domain }) // The argument here is nowhere documented
  .then(credentials => {
      console.log(credentials);
      let client = new BillingManagement(credentials, subscriptionId);
      return client.invoices.list();
  })
  .then(invoices => {
      console.log('List of invoices:');
      console.dir(invoices, { depth: null, colors: true });
  });

Running this shows a nice access_token and invoices

...
List of invoices:
[
  {
    id: '/subscriptions/../providers/Microsoft.Billing/invoices/....',
    name: '...',
    type: 'Microsoft.Billing/invoices',
    invoicePeriodStartDate: 2019-08-25T00:00:00.000Z,
    invoicePeriodEndDate: 2019-09-24T00:00:00.000Z,
    billingPeriodIds: [
      '/subscriptions/.../pr..s/Micro..ing/bill..ods/201910-1'
    ]
  },
  {
    id: '/subscriptions/9ea...3d/providers/Microsoft.Billing/invoices/201909-...',
    name: '....',
    type: 'Microsoft.Billing/invoices',
    invoicePeriodStartDate: 2019-07-25T00:00:00.000Z,
    invoicePeriodEndDate: 2019-08-24T00:00:00.000Z,
    billingPeriodIds: [
      '/subscriptions/..../providers/Microsoft.Billing/billingPeriods/201909-1...'
    ]
  }
]

Although I have my invoices, there are no numbers. And I would like to retrieve costs for every resources.

So the documentation seems to be outdated up to not existing for what I want (as it seems). My question is if someone was able to retrieve information like this? I would really like to know how!!

UPDATE It seems to be a permission issue. So, below I share some screenshots showing what I have right now. Maybe from these it is clear what I miss or have setup incorrectly. So first, here is my latest nodejs app:

const msRestAzure = require("ms-rest-azure");
const ConsumptionManagementClient = require("azure-arm-consumption");

const clientId = '76d79....';          // App registration ID
const secret = '****...';              // App registration secret
const domain =  'dc36...';             // tenantId
const subscriptionId = '9ea2d...';     // subscription ID

const AzureServiceClient = msRestAzure.AzureServiceClient;

//an example to list resource groups in a subscription
msRestAzure.loginWithServicePrincipalSecret(clientId, secret, domain).then((creds) => {
    const client = new ConsumptionManagementClient(creds, subscriptionId);
    const expand = '';
    const filter = '';
    const skiptoken = '';
    const top = 1000;
    const apply = '';
    return client.usageDetails.list(expand, filter, skiptoken, top, apply).then(result => {
    console.log('The result is:', result);
  });
}).catch((err) => {
  console.log('An error occurred:');
  console.dir(err, { depth: null, colors: true });
});

Which outputs a statusCode 401

Error: Unauthorized. Request ID: e6b127...
...

So, I have in AD an App registration

在此处输入图像描述

Its API permissions are

在此处输入图像描述

Finally, I have just one subscription

在此处输入图像描述

With the following IAM settings

在此处输入图像描述

Any suspicious?

If you're looking for resource costs, I would suggest that you take a look at Consumption API - List Usage Details . That will give you the consumption for all the resources.

You will need to install azure-arm-consumption package.

Here's the sample code:

const msRestAzure = require("ms-rest-azure");
const ConsumptionManagementClient = require("azure-arm-consumption");
msRestAzure.interactiveLogin().then((creds) => {
    const subscriptionId = "<your subscription id>";
    const client = new ConsumptionManagementClient(creds, subscriptionId);
    const expand = "";
    const filter = "";
    const skiptoken = "";
    const top = 1000;
    const apply = "";
    return client.usageDetails.list(expand, filter, skiptoken, top, apply).then((result) => {
      console.log("The result is:");
      console.log(result);
    });
}).catch((err) => {
  console.log('An error occurred:');
  console.dir(err, {depth: null, colors: true});
});

This is taken from here: https://github.com/Azure/azure-sdk-for-node/tree/master/lib/services/consumptionManagement .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM