Contents

Create Azure Cost Management exports

How to set up Cost Management exports in Azure


Lets dig into some of the ways we can export the monthly costs of the resources the we have deployed in Microsoft Azure.

Create Azure Cost Management exports

Recently I wanted to setup a monthly cost export for all the Virtual Machines (VM’s) and Managed Disks in a given subscription in Microsoft Azure. Aslong as you have ben assigned the Owner \ Contributor role on the subscription or have been assigned the Cost Management Reader role scoped to the Subscription, then you should be able to access the cost data.

In the Azure Portal head over to Subscriptions and select a subscription from the list. When you have the Subscription pane open, there will be an option on the left side of the screen to go to Cost analysis.

/2022/06/azure-cost-management-exports/azureCostAnalysis.webp
Azure Cost Analysis

In the top of the screen you will see a pill button which shows the current selected scope. You can change this to another subscription if you like or scope to a particular resource group instead of the whole subscription.

You have access to a lot of different visualizations from here. Feel free to play around.

As mentioned earlier I wanted to see the costs over last month for both Virtual Machine and Managed Disks resources. You can get a report for this by setting VIEW to CostByResource, setting the date pill to Last month and by adding a filter on Resource type and selecting both Microsoft.Compute/disks and Microsoft.Compute/virtualMachines.

/2022/06/azure-cost-management-exports/azureCostAnalysisByResource.webp
Azure Cost Analysis - CostByResource

Great! We have all the cost data that we need. Time to figure out how we can export this. Or if this is all the information you were looking for you can also download an export in csv format by pressing the Download button at the top of this page.

Cost Management scheduled exports

Cost analysis has a data export feature builtin. The following documentation describes how you can setup an export schedule for your subscription(s): Tutorial: Create and manage exported data. You can easily setup exports to a Storage Account with this approach in only a few steps. Pretty straight forward! I stumbled on a problem however because the following prerequisite is mentioned:

The storage account must not have a firewall configured.

This is a blocker for me. Having a firewall configured is a security requirement in a lot of companies and often enforced by Azure Policy. Aslong your storage accounts have a firewall configured the Storage Account will not show up in the Cost Management export configuration.

That sucks a bit.. But perhaps we can do something with the Cost Management API directly. Lets find out!

Cost Management APIs

The Microsoft Documentation has a very nice page referencing all the Azure REST APIs. Select Cost Management from the list of APIs on the left side of the screen and click on Overview.

API usage
These APIs are currently only available for Azure Enterprise customers.

In the overview page we can see a table displaying the three REST Operation Groups that are available to us. Dimensions, Query and Exports. The Exports operation group can be used to schedule and/or manage exports. Of course a storage account is still required in order to set these up. So instead of heading over the exports we are interested in the Query operations group. We will also be having a look at the Dimensions operations group later since this can also retrieve some information that we need.

Go to the Usage page and select Usage. At the top of the page a POST request will be displayed along with the URI and its required parameters. The request body and responses are also listed. Aswell as a whole bunch of examples requests. Before we have a look at the example requests lets give the API a try by selecting the Try It option at the top. Sign in into your Microsoft account and confirm that you would like to continue.

The following should display:

/2022/06/azure-cost-management-exports/azureCostAnalysisQuery.webp
Azure Cost Analysis - API Query

Of course instead of using this you could also use an API client like Postman and/or Insomnia to investigate the API.

For the parameters only two are required. The scope and the api-version. The api-version is already populated for the latest available version. We want to display a cost report of resources within our subscription so to achieve that we can specify for the scope subscriptions/subscriptionid, which will look something like subscriptions/xxxx-xxxx-xxxx-xxxx.

Then coming to the body of the request. This is currently empty. In the Sample Requests section of the Usage API page there are a lot of examples. Feel free to run a few of them. Based on the filters that we have set earlier on the Cost Analysis dashboard I came up with the following query:

 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
{
    "type": "Usage",
    "timeframe": "TheLastMonth",
    "dataset": {
        "granularity": "None",
        "aggregation": {
            "totalCost": {
                "name": "PreTaxCost",
                "function": "Sum"
            }
        },
        "filter": {
            "dimensions": {
                "name": "ResourceType",
                "operator": "In",
                "values": [
                    "Microsoft.Compute/virtualMachines",
                    "Microsoft.Compute/disks"
                ]
            }
        },
        "grouping": [
            {
                "type": "Dimension",
                "name": "ResourceId"
            }
        ]
    }
}

We are looking for the data from last month, resources of the types Microsoft.Compute/virtualMachines and/or Microsoft.Compute/disks and we are grouping by the ResourceId in order to get the sum of the costs.

If you are interested in all dimensions that are available you can list them all through the Dimensions operations group API. The API will list all the dimensions by the defined scope.

Invoking the REST Method using PowerShell

Now that we know how to use the API we should find out a way on how to use it. I usually work with Azure using PowerShell and/or the Azure CLI. In this case I went with the Az PowerShell module. We can leverage the command Invoke-AzRestMethod to work with Rest APIs. With the knowledge we gained earlier this is quite easy. All we need to provide to the Cmdlet is the URI path, the REST Method and the Payload. This will look something like the following script:

 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$payload = '{
    "type": "Usage",
    "timeframe": "TheLastMonth",
    "dataset": {
        "granularity": "None",
        "aggregation": {
            "totalCost": {
                "name": "PreTaxCost",
                "function": "Sum"
            }
        },
        "filter": {
            "dimensions": {
                "name": "ResourceType",
                "operator": "In",
                "values": [
                    "Microsoft.Compute/virtualMachines",
                    "Microsoft.Compute/disks"
                ]
            }
        },
        "grouping": [
            {
                "type": "Dimension",
                "name": "ResourceId"
            }
        ]
    }
}'

$apiArguments = @{
    Path = "/subscriptions/{0}/providers/Microsoft.CostManagement/query?api-version={1}" -f (get-azcontext).Subscription.Id, '2021-10-01'
    Method = 'POST'
    Payload = $payload
}
$output = Invoke-AzRestMethod @apiArguments

$output = ($output.Content | ConvertFrom-Json).properties.rows | ForEach-Object {
    $preTaxCost, $resourceId, $currency = $_
    $resourceGroup, $providerPre, $providerType, $resource = ($resourceId -split '/')[4,6,7,8]
    [PSCustomObject]@{
        Resource = $resource
        ResourceType = '{0}/{1}' -f $providerPre, $providerType
        ResourceGroup = $resourceGroup
        PreTaxCost = $preTaxCost
        Currency = $currency
        # ResourceId = $resourceId
    }
}

$output | Format-Table

Since the response is in JSON we can use ConvertFrom-Json to parse the content into objects. The data that we are after is stored in properties.rows. Because each row is stored in an object of its own I am using ForEach-Object to iterate through them, in order to format the data to my liking (mainly based on the resource ids that are returned) and stored them in a PSCustomObject. Of course you can tweak this to however you like. You can also join these results with other data e.g. the Azure subscription usage details (which you can retrieve through the Get-UsageAggregates cmdlet).

After authenticating with Azure (using Connect-AzAccount) and setting the active subscription. We can run the above script and the output will display as follows:

/2022/06/azure-cost-management-exports/azureCostAnalysisPowerShellOutput.webp
Azure Cost Analysis - PowerShell output

Perfect! Just like what we had seen earlier in the portal.

Format-Table
In the above script I use the Format-Table cmdlet to format the cost data into a table. If you are planning on doing anything else with the data (e.g. exporting the data to a csv file using export-csv) then make sure to remove Format-Table. The format cmdlet transforms the object into a format type which makes it hard to use.

PowerShell Cost Management Query

Of course only after writing this post I realized there is also a PowerShell cmdlet available in the Az.CostManagement module. I should have checked on this first! So instead of using the above method you can also straight up use this cmdlet: Invoke-AzCostMangementQuery.

Usage should be quite similar to what we have done above only instead of providing the payload in JSON you can just pass in the properties that you need. You may also require the cmdlet New-AzCostManagementQueryComparisonExpressionObject (man this command has a long name) for setting some of the objects that you need to pass in.

Scheduling Cost Exports

Now that we know how to export the Cost Analysis data we can create a script using the above methods. We can easily write this data to a csv file (by using Export-Csv or something similar) and upload this to a storage account or some other location.

For scheduling we could use solutions like for example:

  • Azure Functions
  • Azure Automation Account
  • Azure DevOps / Github job

And many more.

Conclusion

In this post I went over different options you can access the cost data for resources within your Azure Subscription. I also described the different methods you can use to export said data by using the Cost Export service or leveraging the REST API.

I hope you found this post useful. Have a nice day! 👍