Terraform module witch creates billing export on Azure.
FOCUS v1.0 billing export for Azure now available!
This module will create a storage account for Azure billing exports.
The FinOps Cost and Usage Specification (FOCUS™) is an open-source specification that defines clear requirements for cloud vendors to produce consistent cost and usage datasets.
Supported by the FinOps Foundation, FOCUS™ aims to reduce complexity for FinOps Practitioners so they can drive data-driven decision-making and maximize the business value of cloud, while making their skills more transferable across clouds, tools, and organizations.
Learn more about FOCUS in this FinOps Foundation Insights article.
Detailed examples are available under the ./examples
directory.
Create a FOCUS export for a billing account with a new resource group, storage account and container
module "azurerm_billing_export" {
source = "IAmFrench/billing-export/azurerm"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints
create_resource_group = true
resource_group_name = "rg-focus-export-001"
resource_group_location = "Switzerland North"
create_storage_account = true
storage_account_name = "billingexportokjdlksa"
create_storage_container = true
storage_container_name = "focus"
export_type = "FOCUS"
export_version = "1.0r2"
export_scope_and_id = {
scope = "billing-account"
id = "123456789"
}
export_start_date = local.export_start_date
export_creation_date = "2024-10-16"
export_end_date = "2050-01-01"
enable_backfill = true
export_directory = "billing_account_123456789"
export_name = "focus-export-for-billing-account-123456789"
}
Create a FOCUS export for a billing account with an existing resource group, storage account and container
module "azurerm_billing_export" {
source = "IAmFrench/billing-export/azurerm"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints
create_resource_group = false
resource_group_name = "rg-focus-export-001"
resource_group_location = "Switzerland North"
create_storage_account = false
storage_account_name = "billingexportokjdlksa"
create_storage_container = false
storage_container_name = "focus"
export_type = "FOCUS"
export_version = "1.0r2"
export_scope_and_id = {
scope = "billing-account"
id = "123456789"
}
export_start_date = local.export_start_date
export_creation_date = "2024-10-16"
export_end_date = "2050-01-01"
enable_backfill = true
export_directory = "billing_account_123456789"
export_name = "focus-export-for-billing-account-123456789"
}
Create a FOCUS export for a subcription with a existing resource group but new storage account and container
module "azurerm_billing_export" {
source = "IAmFrench/billing-export/azurerm"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints
create_resource_group = false
resource_group_name = "rg-focus-export-001"
resource_group_location = "Switzerland North"
create_storage_account = true
storage_account_name = "billingexportzfcxfd"
create_storage_container = true
storage_container_name = "focus"
export_type = "FOCUS"
export_version = "1.0r2"
export_scope_and_id = {
scope = "subscription"
id = "12345-uuid-6789"
}
export_start_date = local.export_start_date
export_creation_date = "2024-10-16"
export_end_date = "2050-01-01"
enable_backfill = true
export_directory = "subscription_12345-uuid-6789"
export_name = "focus-export-for-subscription-12345-uuid-6789"
}
- FOCUS
1.0
&1.0r2
export (Improved export experience) - Subscription export (
export_scope_and_id
=subscription
) - Billing Account export (
export_scope_and_id
=billing-account
) - Automatic backfill from
export_start_date
to export's creation date (export_creation_date
) - Retry implementation (if we hit the rate limit
429 Too Many Requests
)
- Id of backfill jobs is not returned by the microsoft API on job submission, therefore returned id is incorrect
FocusCost is not supported
╷
│ Error: Failed to create/update resource
│
│ with module.azurerm_billing_export.azapi_resource.focus_export[0],
│ on ../../main.tf line 100, in resource "azapi_resource" "focus_export":
│ 100: resource "azapi_resource" "focus_export" {
│
│ creating/updating Resource: (ResourceId
│ "/subscriptions/xxxx-xxxx-xxxx-xxxx/providers/Microsoft.CostManagement/exports/focus-export-for-subscription-xxxx-xxxx-xxxx-xxxx"
│ / Api Version "2023-07-01-preview"): PUT
│ https://management.azure.com/subscriptions/xxxx-xxxx-xxxx-xxxx/providers/Microsoft.CostManagement/exports/focus-export-for-subscription-xxxx-xxxx-xxxx-xxxx
│ --------------------------------------------------------------------------------
│ RESPONSE 400: 400 Bad Request
│ ERROR CODE: BadRequest
│ --------------------------------------------------------------------------------
│ {
│ "error": {
│ "code": "BadRequest",
│ "message": "Request properties validation failed: Export type: FocusCost is not supported for Agreement Type: WebDirect and Subscription."
│ }
│ }
│ --------------------------------------------------------------------------------
│
╵
Check if your subscription type is supported here: https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/tutorial-improved-exports#understand-data-types
Name | Version |
---|---|
terraform | >= 1.1.0 |
azapi | >= 2.0.0-beta, < 3.0 |
azurerm | >= 3.113.0, < 5.0 |
time | >= 0.12.1, < 1.0.0 |
Name | Version |
---|---|
azapi | >= 2.0.0-beta, < 3.0 |
azurerm | >= 3.113.0, < 5.0 |
time | >= 0.12.1, < 1.0.0 |
Name | Source | Version |
---|---|---|
months_to_backfill | ./modules/months_to_backfill | n/a |
Name | Type |
---|---|
azapi_resource.focus_export | resource |
azapi_resource_action.backfill_job | resource |
azurerm_resource_group.main | resource |
azurerm_storage_account.export | resource |
azurerm_storage_container.focus | resource |
time_static.export_creation_date | resource |
azurerm_resource_group.main | data source |
azurerm_storage_account.export | data source |
azurerm_storage_container.focus | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
create_resource_group | Option to create or not the Resource Group for the billing export. If set to false , this module will not create the resource group and will instead lookup for a resource group with the name var.resource_group_name .E.g.: true , false |
bool |
false |
no |
create_storage_account | Option to create or not the storage account for the billing export. If set to false , this module will not create the storage account.E.g.: true , false |
bool |
true |
no |
create_storage_container | Option to create or not the Storage Container for the billing export. If set to false , this module will not create the storage Container and willinstead lookup for a storage container with var.storage_container_name in the var.storage_account_name Storage Account.Note: If var.create_storage_account is set to true , then this variable MUST be set to true .E.g.: true , false |
bool |
true |
no |
enable_backfill | Option to enable or not a backfill for the export. E.g.: true , false |
bool |
false |
no |
export_creation_date | Creation date of the export. E.g.: 2024-07-22 |
string |
n/a | yes |
export_directory | Directory to place the billing export in. Validation: Directory name cannot end with a forward slash(/) or dot(.) E.g.: subscription_63aa77b3-5e14-4c6d-a895-27f9d8443e37 with 63aa77b3-5e14-4c6d-a895-27f9d8443e37 being the subscription id |
string |
n/a | yes |
export_end_date | End date of the export. Validation: Date should be in the future and it must be the first day of the month. E.g.: 2050-01-01 |
string |
"2050-01-01" |
no |
export_name | Name of the billing export. Validation: Export name must be alphanumeric, without whitespace, and 3 to 64 characters in length. E.g.: focus-export-for-sub-63aa77b3-5e14-4c6d-a895-27f9d8443e37 (57 characters) |
string |
n/a | yes |
export_scope_and_id | Scope and the corresponding id for the billing export. Valid values for scope are: - billing-account for an export at the billing account level (recommended)- subscription for an export at the subscription levelE.g.: { |
object({ |
n/a | yes |
export_start_date | Start date of the export. You can go as far as 9 years in the past. Validation: Date should be in the past and it must be the first day of the month. E.g.: 2024-01-01 |
string |
"2020-01-01" |
no |
export_type | Version of the billing export. Valid values: - FOCUS for Cost and usage details (FOCUS), - AMORTIZED for Cost and usage details (amortized), - ACTUAL for Cost and usage details (usage only)Learn more about export types: https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/tutorial-improved-exports#schedule-frequency E.g.: FOCUS , AMORTIZED or ACTUAL |
string |
n/a | yes |
export_version | Version of the billing export. Should be use with export_type .Valid values are: - 1.0r2 & 1.0 for FOCUS - 2023-12-01-preview for Cost and usage details (EA, MCA, MPA and CSP)- 2019-11-01 for Cost and usage details (MOSA)E.g.: 1.0r2 , 1.0 , 2023-12-01-preview , 2019-11-01 |
string |
n/a | yes |
resource_group_location | Location of the Storage Account. Note: if var.create_resource_group is set to true , then this variable MUSTbe set. E.g.: Switzerland North |
string |
null |
no |
resource_group_name | Name of the resource group where the Storage account is located in. E.g.: rg-finops-export-001 |
string |
n/a | yes |
storage_account_location | Location of the Storage Account. If null , the Storage Account will be created in the location linked to the resource group.E.g.: Switzerland North |
string |
null |
no |
storage_account_name | Name of the Storage Account. The Storage Account will be created with this name if var.create_storage_account is true .E.g.: billingexports |
string |
n/a | yes |
storage_container_name | Name of the Storage Container. The Storage Container will be created with this name if var.create_storage_container is true .E.g.: focus-v1.0 |
string |
n/a | yes |
tags | Tags to apply to all created resources. E.g.: { |
map(string) |
{ |
no |
Name | Description |
---|---|
backfill_job_id | List of Ids of backfill jobs. E.g.: [ |
export_id | Id of the export. E.g.: /providers/Microsoft.Billing/billingAccounts/123456789/providers/Microsoft.CostManagement/exports/focus-export-for-billing-account-123456789 |
months_to_backfill | List of months to backfill. E.g.: [ |