services | platforms | author |
---|---|---|
app-service, functions |
nodejs |
ityer |
On-demand calculation of Azure consumption cost
This sample demonstrates how to use the Azure billing commerce APIs to find consumption cost per subscription and resource-groups. The sample is implemented as an Azure Function.
The challenge
The Billing API and the Consumption API don't expose the cost of consumption. Instead, the API only exposes the ability to interact with past invoices or receive consumption quantities without cost data.
For example, you can find out that a subscription had five compute hours, but response does not include the cost per compute unit.
In addition, some functions are also not available for sponsored accounts.
Explaining the solution
The Azure Commerce APIs expose two functions:
-
Resource usage: Returns consumption data for an Azure subscription
-
Resource RateCard: Returns price and metadata information for resources used in an Azure subscription, primarily a price for each meter.
This sample exposes a wrapper around the billing APIs to create a simple interface for calculating costs.
There are four steps to extract the cost:
- Authenticate to Azure and obtain the
Credentials
object. - Use the
Credentials
object to pullrateCards
which are the rates set up for the given account (Rate
is also calledMeters
). - Use the
Credentials
object to pullConsumption
data for each resource in the given subscription. Each consumption listing contains theMeter ID
from the rate cards. Consumption provides you with a quantity per meterID. - The last step is to multiply the rate value with the consumption quantity. The result of this calculation represents the
cost
.
Results can be filtered by resource group or resource tags. The Node.js code makes use of the Azure node.js SDKs.
Deploy the sample to Azure
The automated deployment provisions an Azure Storage account and an Azure Function in a Dynamic compute plan and sets up deployment from source control.
When you set up the Azure Function, you supply information and credentials to initialize the function. This is a one-time step. Make sure you have the following information available:
Name | Type | Description |
---|---|---|
clientId |
string | Your service principal ID. If you don't already have one you may need to create a service principal. |
clientSecret |
string | Your service principal secret |
tenantId |
string | Your subscription tenant ID. You can find the tenant ID through the portal. |
subscriptionId |
string | Subscription ID to pull consumption info for. You can find the subscription ID through the portal |
offerId |
string | Must be specific code taken from Microsoft Azure Offer Details |
The deployment template has a parameter named manualIntegration
which controls whether or not a deployment trigger is registered with GitHub. Use true
if you are deploying from the main Azure-Samples repo (which does not register a hook), or false
not to register the hook. Since a value of false
registers the hook with GitHub, the deployment will fail if you don't have write permissions to the repo.
If you want to deploy it from your own repo, make sure your account is authorized with GitHub.com, otherwise the deployment fails with an authentication error.
Calling the function
Once the template is deployed, two functions are created under the App service
:
-
get-consumption-cost-node
: The function logs in into Azure and pulls the rate and consumption data to calculate the actual cost based on these values. -
download-consumtion-cost
: The function logs into Azure and uses the rate and consumption data to calculate a detailed report of the actual cost of each resource. The result is a.csv
file which you can download from the function.
Optional parameters:
Name | Type | Description |
---|---|---|
detailed |
bool | true if the consumption info should contain details. Relevant only for get-consumption-cost-node |
filter |
string | A way to limit results only to a specific resource instance info. For example: resource group, tags etc. |
startDate |
Date | Start time for the report. The date format is ECMAScript YYYY-MM-DDTHH:mm:ss.sssZ . Defaults to 24 hours ago |
endDate |
Date | End time for the report. The date format is ECMAScript YYYY-MM-DDTHH:mm:ss.sssZ . Defaults to now. |
granularity |
string | Values: Daily (default) or Hourly |
The parameters are sent as json
in the body of the POST request.
get-consumption-cost-node
function
Executing the The following code listing is an example of calling the get-consumption-cost-node
function (make sure to replace values with your deployment info):
curl -H "Content-Type: application/json" -X POST -d '{"filter":"<resource-group-name>","detailed":"true"}' https://<app-service-name>.azurewebsites.net/api/get-consumption-cost-node?code=<code>
If the function is called from a mobile client or a JavaScript web app, we recommend that you add authentication to your Function using App Service Authentication/Authorization. The API key is insufficient for security purposes since it can be discovered by sniffing traffic or decompiling the client app.
The function takes a considerable amount of time (in seconds) to execute because it performs three API calls: Log in, Get Rates and Get Consumption. A real-world scenario would include use of caching and user sessions to avoid multiple logins and calls to the API.
The response
Response from the wrapper is an object in the form of:
{ total: (Number, the total cost), details: (Key-Value pairs of resource and cost)}
For example:
{ total: 10.3, details: { res1:5, res2: 5.3}}
download-consumtion-cost
function
Executing the The following code listing is an example of calling the download-consumtion-cost
function. It will download a detailed report in a csv
format (make sure to replace values with your deployment info):
curl -H "Content-Type: application/json" -X POST -d '{"filter":"<resource-group-name>","granularity":"Hourly"}' https://<app-service-name>.azurewebsites.net/api/download-consumtion-cost?code=<code>
If the function is called from a mobile client or a JavaScript web app, we recommend that you add authentication to your Function using App Service Authentication/Authorization. The API key is insufficient for security purposes since it can be discovered by sniffing traffic or decompiling the client app.
The function takes a considerable amount of time (in seconds) to execute because it performs three API calls: Log in, Get Rates and Get Consumption. A real-world scenario would include use of caching and user sessions to avoid multiple logins and calls to the API.
The response
Response from the wrapper is a csv
file having the following columns:
- name: meter name
- rate: meter rate,
- consumption: meter consumption
- cost: cost of meter consumption
- region: Azure region
- meterDescription: textual description
- usageStartTime: start time
- usageEndTime: end time
- resourceGroup