Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/iamfrench/terraform-azurerm-billing-export
Terraform Module witch creates billing export, including FOCUS, on Azure.
https://github.com/iamfrench/terraform-azurerm-billing-export
azure azure-billing billing-export finops finops-focus focus terraform terraform-module
Last synced: 8 days ago
JSON representation
Terraform Module witch creates billing export, including FOCUS, on Azure.
- Host: GitHub
- URL: https://github.com/iamfrench/terraform-azurerm-billing-export
- Owner: IAmFrench
- License: apache-2.0
- Created: 2024-07-24T06:48:22.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-11-15T21:23:54.000Z (about 1 month ago)
- Last Synced: 2024-12-07T00:04:30.930Z (16 days ago)
- Topics: azure, azure-billing, billing-export, finops, finops-focus, focus, terraform, terraform-module
- Language: HCL
- Homepage: https://registry.terraform.io/modules/IAmFrench/billing-export/azurerm/latest
- Size: 58.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Citation: CITATIONS.cff
Awesome Lists containing this project
README
# Microsoft Azure Billing export Terraform Module
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.
## What is FOCUS™?
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](https://www.finops.org/insights/focus-1-0-available/).
## Usage
Detailed examples are available under the [`./examples`](./examples/) directory.
Create a FOCUS export for a billing account with a new resource group, storage account and container
```hcl
module "azurerm_billing_export" {
source = "IAmFrench/billing-export/azurerm"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
```hcl
module "azurerm_billing_export" {
source = "IAmFrench/billing-export/azurerm"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
```hcl
module "azurerm_billing_export" {
source = "IAmFrench/billing-export/azurerm"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"
}
```## Roadmap & Features
- [X] FOCUS `1.0` & `1.0r2` export ([Improved export experience](https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/tutorial-improved-exports))
- [X] Subscription export (`export_scope_and_id` = `subscription`)
- [X] Billing Account export (`export_scope_and_id` = `billing-account`)
- [X] Automatic backfill from `export_start_date` to export's creation date (`export_creation_date`)
- [X] Retry implementation (if we hit the rate limit `429 Too Many Requests`)## Limitations
- Id of backfill jobs is not returned by the [microsoft API](https://learn.microsoft.com/en-us/rest/api/cost-management/exports/execute) on job submission, therefore returned id is incorrect
## Common errors
### FocusCost is not supported
FocusCost is not supported
```bash
╷
│ 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
## Requirements
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.1.0 |
| [azapi](#requirement\_azapi) | >= 2.0.0-beta, < 3.0 |
| [azurerm](#requirement\_azurerm) | >= 3.113.0, < 5.0 |
| [time](#requirement\_time) | >= 0.12.1, < 1.0.0 |## Providers
| Name | Version |
|------|---------|
| [azapi](#provider\_azapi) | >= 2.0.0-beta, < 3.0 |
| [azurerm](#provider\_azurerm) | >= 3.113.0, < 5.0 |
| [time](#provider\_time) | >= 0.12.1, < 1.0.0 |## Modules
| Name | Source | Version |
|------|--------|---------|
| [months\_to\_backfill](#module\_months\_to\_backfill) | ./modules/months_to_backfill | n/a |## Resources
| Name | Type |
|------|------|
| [azapi_resource.focus_export](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource) | resource |
| [azapi_resource_action.backfill_job](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) | resource |
| [azurerm_resource_group.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_storage_account.export](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource |
| [azurerm_storage_container.focus](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container) | resource |
| [time_static.export_creation_date](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/static) | resource |
| [azurerm_resource_group.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source |
| [azurerm_storage_account.export](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/storage_account) | data source |
| [azurerm_storage_container.focus](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/storage_container) | data source |## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [create\_resource\_group](#input\_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](#input\_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](#input\_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 will
instead 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](#input\_enable\_backfill) | Option to enable or not a backfill for the export.
E.g.: `true`, `false` | `bool` | `false` | no |
| [export\_creation\_date](#input\_export\_creation\_date) | Creation date of the export.
E.g.: `2024-07-22` | `string` | n/a | yes |
| [export\_directory](#input\_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](#input\_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](#input\_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](#input\_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 level
E.g.:{|
scope = "billing-account"
id = "1234567890"
}object({| n/a | yes |
scope = string
id = string
})
| [export\_start\_date](#input\_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](#input\_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](#input\_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](#input\_resource\_group\_location) | Location of the Storage Account.
Note: if `var.create_resource_group` is set to `true`, then this variable MUST
be set.
E.g.: `Switzerland North` | `string` | `null` | no |
| [resource\_group\_name](#input\_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](#input\_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](#input\_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](#input\_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](#input\_tags) | Tags to apply to all created resources.
E.g.:{| `map(string)` |
createdBy = "Terraform"
}{| no |
"createdBy": "Terraform"
}## Outputs
| Name | Description |
|------|-------------|
| [backfill\_job\_id](#output\_backfill\_job\_id) | List of Ids of backfill jobs.
E.g.:[|
"/providers/Microsoft.Billing/billingAccounts/123456789/providers/Microsoft.CostManagement/exports/focus-export-for-billing-account-123456789/Run/e8102b07-9d1e-4185-95fe-fe60d8d6ad5a",
"/providers/Microsoft.Billing/billingAccounts/123456789/providers/Microsoft.CostManagement/exports/focus-export-for-billing-account-123456789/Run/1089e775-8098-4d50-ae69-c22fd26ae7ef"
]
| [export\_id](#output\_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](#output\_months\_to\_backfill) | List of months to backfill.
E.g.:[|
{
start = "2023-01-01T00:00:00Z"
end = "2023-01-31T00:00:00Z"
},
{
start = "2023-02-01T00:00:00Z"
end = "2023-02-28T00:00:00Z"
}
]