Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions docs-mslearn/toolkit/hubs/data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: FinOps hubs data model
description: Learn about the tables and functions available in FinOps hubs to build your own queries, reports, and dashboards.
author: flanakin
ms.author: micflan
ms.date: 04/01/2026
ms.date: 07/26/2026
ms.topic: reference
ms.service: finops
ms.subservice: finops-toolkit
Expand Down Expand Up @@ -52,15 +52,22 @@ Note the use of "Data Explorer" covers both Azure Data Explorer and Microsoft Fa

## Schema version

One of the goals of the FinOps hubs data model is to guarantee backwards compatibility. To support this, each FinOps hub release uses a specific schema version which aligns to a specific FOCUS version. The **schema version** defines the columns, data types, and allowed values in the tables and functions for each [managed dataset](#managed-datasets-in-finops-hubs).
One of the goals of the FinOps hubs data model is to guarantee backwards compatibility. To support this, each FinOps hub release uses a specific schema version which aligns to a specific FOCUS version. For instance, the `v1_4` schema version aligns with FOCUS 1.4 and the `v1_2` schema with FOCUS 1.2. The **schema version** defines the columns, data types, and allowed values in the tables and functions for each [managed dataset](#managed-datasets-in-finops-hubs).

During ingestion, data is transformed to the schema version of your current FinOps hub release, regardless of the FOCUS version of the source data. For instance, if your hub uses the `v1_4` schema, incoming FOCUS 1.0 data is converted to FOCUS 1.4 as it's ingested. Data ingested by an earlier release stays in the schema version it was originally ingested into. For instance, data ingested when your hub used the `v1_2` schema remains in the `v1_2` format even after you upgrade to a newer schema version.

The functions in the `Hub` database pull from all tables and transform them into a specific version. For instance, `Costs_v1_0` will convert `v1_4` and `v1_2` data back to the `v1_0` format, ensuring backwards compatibility despite upgrading to newer versions. When you're ready to upgrade, you can selectively upgrade each report or integration to use `Costs_v1_2` or `Costs_v1_4` without breaking others. However, if you want a quick, convenience function that always returns the latest version, you can use the unversioned functions, like `Costs` and `Prices`. Unversioned functions are convenient for ad hoc use while versioned functions are recommended for integration points that require a consistent format after upgrades.

The following table indicates the schema version for each FinOps hub release and which FOCUS version they align to.

| Release | Schema | FOCUS version |
| ------- | ------ | ------------- |
| 12+ | `v1_2` | 1.2 |
| 15+ | `v1_4` | 1.4 |
Comment thread
flanakin marked this conversation as resolved.
| 12-14 | `v1_2` | 1.2 |
| 0.7-11 | `v1_0` | 1.0 |

Cost Management export availability for a given FOCUS version is separate from FinOps hub support for that version. FinOps hubs transforms export data to the schema version of your current release during ingestion, whether the export uses an older or newer FOCUS version than that schema.

<br>

## Managed datasets in FinOps hubs
Expand All @@ -81,7 +88,7 @@ Managed datasets also include the following assets for FinOps hubs with Data Exp
- An unversioned function in the **Hub** database (for example, **Costs()**).
- A table in Power BI KQL reports that wraps the corresponding versioned function.

During data ingestion, FinOps hubs transform data to the latest supported [schema version](#schema-version). Unversioned functions, like **Costs()**, use the latest schema version. Unversioned functions, like **Costs_v1_0()**, are backwards compatible, should remain consistent, and do not need to change when upgrading your FinOps hub instance. To learn more about the data ingestion process, see [How data is processed in FinOps hubs](data-processing.md).
During data ingestion, FinOps hubs transform data to the latest supported [schema version](#schema-version). Unversioned functions, like **Costs()**, use the latest schema version. Versioned functions, like **Costs_v1_0()**, are backwards compatible, should remain consistent, and do not need to change when upgrading your FinOps hub instance. To learn more about the data ingestion process, see [How data is processed in FinOps hubs](data-processing.md).

When querying data in FinOps hubs, always use the **Hub** database and avoid working with the tables and functions in the **Ingestion** database. Use unversioned functions for ad-hoc analysis or reports that do not require long-term backwards compatibility. Use the versioned functions for reports or systems that do require backwards compatibility and you do not want to be impacted by FinOps hub updates, which may change column names, data types, and values.

Expand Down
36 changes: 26 additions & 10 deletions src/templates/finops-hub/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

## Data ingestion workflow

- All data is ingested into tables named "*_raw".
- All data is ingested into tables named "\*\_raw".
- Raw tables are declared in [IngestionSetup_raw.kql](../modules/scripts/IngestionSetup_raw.kql).
- These tables have a union schema to support multiple sources and versions.
- All data is transformed to the latest FOCUS schema using an update policy into a "*_final_vX_Y" table named after the version (for example, "1.0" = "_v1_0"). Final tables, Transform functions, and update policies are in the versioned setup files:
- All data is transformed to the latest FOCUS schema using an update policy into a "\*\_final_vX_Y" table named after the version (for example, "1.0" = "\_v1_0"). Final tables, Transform functions, and update policies are in the versioned setup files:
- [IngestionSetup_v1_0.kql](../modules/scripts/IngestionSetup_v1_0.kql)
- Data ingestion from previous version of hubs will remain in the versioned tables.
- Data is read from versioned functions in the Hub database. See HubSetup_vX_Y.kql in the [modules/scripts folder](../modules/scripts) for details.
Expand All @@ -17,27 +17,43 @@
- Each versioned function unions data from versioned tables in the Ingestion database and transforms it to that FOCUS version for back compat.
- Consumers should use the unversioned function for the latest and the versioned functions for back compat.

To add a new FOCUS versions:
To add a new FOCUS version:

0. Confirm dependencies
1. Ensure the FOCUS specification has been ratified for the target version. Support for working draft FOCUS versions should not be shipped before official ratification to prevent customer churn since FOCUS working drafts may change without notice.
2. Check whether Microsoft Cost Management has shipped a matching FOCUS export dataset version. The hub depends on a `focuscost_X.Y.json` schema mapping file in [Microsoft.CostManagement/Exports/schemas](../modules/Microsoft.CostManagement/Exports/schemas/) when ingesting from Cost Management. If the export is not yet available, the hub schema can still ship as GA. Note the gap in the changelog so adopters know what additional setup will be required.
Comment thread
flanakin marked this conversation as resolved.
1. Add schema mapping file
1. Create new schema mapping file for the Cost Management export dataset version in the schemas folder
2. Add file to file upload list in [storage.bicep](../modules/storage.bicep)
2. Update ingestion database scripts
1. Add new columns to the *_raw tables per dataset in [IngestionSetup_RawTables.kql](../modules/scripts/IngestionSetup_RawTables.kql)
1. Add new columns to the \*\_raw tables per dataset in [IngestionSetup_RawTables.kql](../modules/scripts/IngestionSetup_RawTables.kql)
2. Save a copy of the latest version of the IngestionSetup_vX_Y.kql using the latest FOCUS version
- If updating the same version, increment the release number (e.g., `r2`)
3. Rename all functions, tables, and policies in the new file to the new version (leave the old as-is)
4. Update the *_final_vX_Y tables to account for any new columns
5. Update the *_transform_vX_Y functions to account for any new columns
6. Update the script to delete the old update policy for the *_raw tables
4. Update the \*\_final_vX_Y tables to account for any new columns
5. Update the \*\_transform_vX_Y functions to account for any new columns
6. Update the script to delete the old update policy for the \*\_raw tables
7. Confirm the new file has the update policy set to use the latest version of the transform function and final table
3. Update hub database scripts
1. Add new FOCUS version section after the latest version section and before existing version sections
2. Create new *_vX_Y functions per dataset that transforms older data to the new FOCUS version
3. Update the unversioned functions to use the new *_vX_Y functions
4. Update older versioned functions to also pull from the new *_vX_Y functions and transform to the old schema
2. Create new \*\_vX_Y functions per dataset that transforms older data to the new FOCUS version
3. Update the unversioned functions to use the new \*\_vX_Y functions
4. Update older versioned functions to also pull from the new \*\_vX_Y functions and transform to the old schema
4. Update reports and dashboards
1. Update the storage reports to use the new columns
2. Update the KQL reports to use the new versioned functions
3. Update the ADX dashboard to use the new versioned functions
4. Update the FOCUS queries in the best practices library to use the new versioned functions
5. Update open-data metadata
1. Create a `FocusCost_<version>.json` file in [src/open-data/dataset-metadata](../../../open-data/dataset-metadata/) for each Cost Management cost export version. `<version>` must match the precise Cost Management export version, including `-preview`, if applicable (for example, `FocusCost_1.2-preview.json`).
2. Create a `FinOpsHubs_<dataset>_<schema-version>.json` file in [src/open-data/dataset-metadata](../../../open-data/dataset-metadata/) for each FinOps hub managed dataset schema version.
3. Mirror the schema details (columns, types, descriptions) from the matching Cost Management export or FinOps hubs schema so downstream consumers see consistent metadata.
6. Update plugin skill files
1. Refresh the FOCUS schema and function references in the following files so plugin guidance does not go stale:
- [src/templates/agent-skills/finops-toolkit/references/finops-hubs.md](../../agent-skills/finops-toolkit/references/finops-hubs.md)
- [src/templates/agent-skills/finops-toolkit/references/finops-hubs-deployment.md](../../agent-skills/finops-toolkit/references/finops-hubs-deployment.md)
- [src/templates/agent-skills/azure-cost-management/references/azure-cost-exports.md](../../agent-skills/azure-cost-management/references/azure-cost-exports.md)
- [src/templates/claude-plugin/agents/ftk-database-query.md](../../claude-plugin/agents/ftk-database-query.md)
- [src/templates/claude-plugin/output-styles/ftk-output-style.md](../../claude-plugin/output-styles/ftk-output-style.md)
7. Update changelog
1. Add an entry under the next version in [docs-mslearn/toolkit/changelog.md](../../../../docs-mslearn/toolkit/changelog.md) describing the new FOCUS version support and any preview status.
Loading