This repo contains the code for a sample Azure Function to retrieve the daily billing data for all subscriptions in an Azure Management Group. It uses an HTTP trigger to start the report generation.
The resulting CSV files (one per subscription found) are stored in an Azure Storage Account you define. The information is retieved via the Azure Cost Management APIs using t{ get; set; } = ""he following process:
- Request report generation for all of the subscriptions in your managment group. The Management group set in the
ManagementGroupId
key in the configuration. The report is generated for the previous day by default or via astartDate
parameter in the query string. - Check the status of each report generation and waits until they are all complete.
- Once complete, copies the files from the default storage account to the storage account and container you designate. The storage account and container are set in the
StorageConnectionString
andContainerName
keys in the configuration.
The destination file will named in the following format with the date path prefixed:yyyy-MM-dd/Billing-{subscription guid}.csv
The HTTP request will return a JSON summary of the report generation as per the below example. You can easily determine if any reports failed to generate via the HTTP return code (200 for success, 424 for any failures) or from the hasFailures
value. The subscriptions that had issues will be in the reports list array with a "success": false
value and a statusMessage
showing the failure reason.
{
"managementGroupId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"startDate": "2023-05-03T00:00:00",
"endDate": "2023-05-03T23:59:59.999",
"success": true,
"failureMessage": null,
"SubscriptionReports": [
{
"subscriptionName": "My Sub name",
"subscriptionId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"tenantId": "YYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY",
"reportStatusUrl": "https://management.azure.com/subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.CostManagement/costDetailsOperationResults/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx?api-version=2022-10-01",
"reportBlobSas": "https://ccmreportstoragewestus3.blob.core.windows.net/armmusagedetailsreportdownloadcontainer/20230504/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx?sv=2018-03-28\u0026sr=b\u0026sig=6TFT5jBp1QRYIrApdrBd4vl%2FTNgeLCw0NViskYMXXl0%3D\u0026spr=https\u0026st=2023-05-04T14%3A30%3A21Z\u0026se=2023-05-05T02%3A35%3A21Z\u0026sp=r",
"offerDurableId": "MS-AZR-#####",
"rateCardUrl": "https://management.azure.com/subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.Commerce/RateCard?api-version=2015-06-01-preview&$filter=OfferDurableId eq 'MS-AZR-#####' and Currency eq 'USD' and Locale eq 'en-US' and RegionInfo eq 'US'",
"rateCardJsonBlobName": "https://XXXXXXXXXX.blob.core.windows.net/billing/2023-06-10/RateCard-XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.json",
"rawCostDataBlobName": "https://XXXXXXXXXX.blob.core.windows.net/billing/2023-06-10/Raw-XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.csv",
"costDataBlobName": "https://XXXXXXXXXX.blob.core.windows.net/billing/2023-06-10/Billing-XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.csv",
"success": true,
"statusMessage": [
"Successfully saved report to Blob storage.",
"Successfully saved rate card mapped report to Blob storage.",
"Successfully saved rate card to Blob storage."
]
}
]
}
- Azure Function App configured with the .NET 7 isolated runtime
- Build and deploy this project to that Function App
- System Assigned Managed Identity for the Function with
Cost Management Reader
orCost Management Contributor
RBAC role - Azure Storage Account with Blob Storage
- App Configuration Settings:
ManagementGroupId
- the value need to be the Guid Id value of the mangement groupStorageConnectionString
- connection string to the Azure storage accountContainerName
- name of the storage container to save the billing report CSV. If is does not exist, it will be created at runtime. The name must adhere to the naming rules.MaxConcurrency
- maximum number of concurrent tasks the app will run. This can be used to tune memory usage and rate throttling (default:2
)UseLegacyRateCard
- If you need to leverage the Legacy RateCard APIs, you can add this configuration setting with the valuetrue
(default:false
)- Additional configuraiton options when using legacy rate card:
SaveRateCardData
- whether or not to save the Rate Card json file to storage (default:true
)SaveRawBillingReport
- whether or not to save raw CSV file (no mapped cost data) to storage (default:true
)OfferDurableId
- the offer durable id to use for the legacy rate card API (default:MS-AZR-0003P
)RateCardPerSubscription
- whether or not to retrieve a rate card per subscription or retrieve one rate card for the first subscription and use this for all of the subscriptions (default:false
). This helps manage memory usage and can be beneficial if all rate cards for the subs is expected to be the same.
- Additional configuraiton options when using legacy rate card:
NOTE: If you have a large number of subscriptions in your management group, you may need to deploy the Function to something other than the "Consumption" tier. This is because the Consumption tier will timeout after 5 minutes.