A few days ago (Mid december 2017), Microsoft officially published the documentation for the Azure Consumption REST-API on the docs website. Link
Enough trigger for me to start playing around with it and share my experiences.
Overview
To begin with, the API offers 6 different categories, which we can summarize down to 4, which are:
1.) Budgets-Preview
In Azure Enterprise subscriptions, its possible to define budgets. This category allows you to do this via REST and do your CRUD (Create, Read, Update, Delete) operations with budgets. As i dot have an enterprise subscription, nothing to dig into for me.
2.) Reservations (Details and Summaries)
Personally, i also never dealt with reservations, but it seems you can reserve resources for departments in a subscription. From REST, you can just list them
3.) Operations
This area is some kind of confusing for me, as it gives you output of what operations you can do with the consumption REST-API (isnt this the thing we are just describing ??), and not actual data from your subscription.
4.) Usage
Now finally, thats where we want to go, usage shows what kind of resources have been used and what costs they generated.
Lets dig into here a little bit deeper.
Prerequisites
Subscription Type
The Consumption REST-API only supports all Azure Subscriptions, except:
- MS-AZR-0145P (CSP)
- MS-AZR-0146P (CSP)
- MS-AZR-159P (CSP)
- MS-AZR-0036P (sponsored)
- MS-AZR-0143P (sponsored)
- MS-AZR-0015P (internal)
- MS-AZR-0144P (DreamSpark)
So be sure you have a subscription with a different type. To check this, login to your Azure account, go your subscription and click on overwiew. You find the type in „Offer ID“
Read access via AppID and AppKey
The easiest (and best in my opinion) way to access your Azure subscription programmatically is via Appid/AppKey. Either you have one already or you generate one, the AppID and AppKey is needed for your Script to authenticate property and read data via PowerShell.
To create one, follow this link: How to generate an AppID/AppKey
Get the Data !
1.) Authenticate and generate a token
With our Appid/AppKey pair we are ready to authenticate and store a Token to use it further in the next steps. Please replace AppID, AppKey, TenantID with your values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$AppId = '<yourAppid Guid here>' $AppkeyPlain = '<yourAppKey here>' $Resource = "https://management.core.windows.net/" $AppKey = $AppKeyPlain|ConvertTo-SecureString -AsPlainText -Force $loginUrl = "https://login.microsoftonline.com" $tenantid = '<your tenantid here>' $body = @{ grant_type="client_credentials"; resource=$Resource; client_id=$AppId; client_secret=(New-Object PSCredential $Appid,$AppKey).GetNetworkCredential().Password; } $token = Invoke-RestMethod -Method Post -Uri $loginUrl/$TenantId/oauth2/token?api-version=1.0 -Body $body |
2.) Get the usage data
Now, we can use the REST query to retrieve some usage data. You need:
- Subscription ID
- Billing Period
The billing periods can be found by opening a Cloud(Power)Shell and use the command Get-AzurermbillingPeriod. Is is usually in the format: yymmdd-1
Now lets prepare the script with some input:
1 2 3 4 5 6 |
# SubscriptionID and Billing Period $SubscriptionId = '<Your subscription GUID here>' $billingperiod = '201706-1' #Create the REST-URL $usageURL = "https://management.azure.com/subscriptions/$subscriptionid/providers/Microsoft.Billing/billingPeriods/$billingperiod/providers/Microsoft.Consumption/usageDetails?api-version=2017-11-30" |
As we have prepared the „dynamic“ values of the REST-Call we compile the whole thing together and store the results in the $Usagedata Variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$body = @{ ts = [System.DateTime]::UtcNow.ToString('o') } $header = @{ 'Authorization' = "$($Token.token_type) $($Token.access_token)" "Content-Type" = "application/json" } $UsageData = Invoke-RestMethod ` -Method Get ` -Uri $usageURL ` -ContentType application/json ` -Headers $header ` -Body $body |
3.) Format the Output to something human readable
$Usagedata contains JSON-formatted output, which we need to bring in some sort of report.
The actual data is stored in $Usagedata.value.properties. Try the below line to retrieve the first 3 records
1 |
$UsageData.value.properties[0..2] |
It is possible to interpret the output, but it doesnt look nice.
The entry tells us that i have spent 3,94 EUR between March 14-15 on OMS. Nice, but thats nothing for the management 🙂
So lets do PowerShell do the work to generate a report. Below you find a simple function to format the $Usagedata variable. You may take the code and write it into your own module as needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
function New-AzureConsumptionreport { [array]$ConsumptionReport = $null #Extract usage data from JSON foreach ($record in ($UsageData.value.properties)) { #Bring output to readable format [DateTime]$Startdate = [datetime]::ParseExact($($record.usageStart).Split('.')[0],'yyyy-MM-ddTHH:mm:ss',$null) [DateTime]$Enddate = [datetime]::ParseExact($($record.usageEnd).Split('.')[0],'yyyy-MM-ddTHH:mm:ss',$null) $Duration = "{0:dd} days, {0:hh} hours, {0:mm} minutes" -f (New-TimeSpan -Start $Startdate -End $Enddate) [String]$ResourceGroup = $record.instanceId.Split('/')[4] [String]$Provider = $($record.InstanceId).Split('/')[6] + "/" + $($record.InstanceId).Split('/')[7] [String]$InstanceName = $record.instanceName $usagequantity = $record.usageQuantity [String]$pretaxcost = "{0:C}" -f $record.pretaxCost [String]$currency = $record.currency # Store output in a ordered hashtable PS Custom object $billingrecord = [Ordered]@{ 'Start' = $Startdate 'End' = $Enddate 'Duration' = $Duration 'Resourcegroup' = $ResourceGroup 'Provider' = $Provider 'Instance Name' = $InstanceName 'Usage quantity' = $usagequantity 'Cost' = $pretaxcost 'Currency' = $currency } $Reportrecord = New-Object -TypeName psobject -Property $Billingrecord $ReportRecord.PSObject.TypeNames.Insert(0,'My.Azure.Consumptionrecord') $ConsumptionReport = [Array]$ConsumptionReport + $Reportrecord } $ConsumptionReport } |
Now, lets simply fire up this function and generate a list of consumption records
1 |
New-AzureConsumptionreport|Select-Object -first 5|format-table |
And thats what i was expecting !
Have fun with testing and experimenting with the Consumption API!
Regards/Roman