From 9d70bc3f5bf11ac987e52a0247e8c50bc2520ff5 Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Sun, 19 Nov 2023 15:03:42 -0800 Subject: [PATCH 01/65] Alphabetize contributor list (#289) --- specification/contributors.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/contributors.md b/specification/contributors.md index e25e21078..81076d2fe 100644 --- a/specification/contributors.md +++ b/specification/contributors.md @@ -25,7 +25,7 @@ Thanks to the following FOCUS members for their contributions to this specificat * Jacky Liu (Google) * Janine Pickard-Green (MagicOrange Group Limited) * Jason Kelly (Anglepoint Group Inc) -* Joe Ferrero (DB Gurus Inc.) +* Joe Ferrero (DB Gurus Inc) * John Grubb (Platform.sh) * Joshua Kwan (Ternary) * Karl Kraft (Walmart) @@ -42,20 +42,20 @@ Thanks to the following FOCUS members for their contributions to this specificat * Mike Polson (VMWare) * Nick Kotze (Surveil) * Nicolas Fonrose (Teevity) +* Peter Marton (OpenMeter.io) * Ray Ding (Accenture) * Ricardo Triana (Accenture) -* Peter Marton (OpenMeter.io) * Riley Jenkins (Domo) * Rodney Joyce (CloudMonitor) * Rupa Patel (Google) -* Sarah McMullin (Google) * Sanjna Srivatsa (VMWare) +* Sarah McMullin (Google) * Shawn Alpay (Envisor) * Sumaira Nazir (Platform.sh) * Tatiana Dubovchenko (Flexera) -* Trey Morgan (Microsoft) * Tim O'Brien (Walmart) +* Trey Morgan (Microsoft) * Trig Ghosh (Accenture) * Udam Dewaraja (FinOps Foundation) -* Yuriy Prykhodko (Amazon Web Services) * Webb Brown (Kubecost) +* Yuriy Prykhodko (Amazon Web Services) From fd308dfafb793caebed63634999e273b930b7170 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 17 Jan 2024 19:34:02 -0800 Subject: [PATCH 02/65] [ADMIN] Update and rename proposal.md to feedback.yml (#291) Update the current `proposal.md` Issue by replacing it with the content agreed upon by the group in [FOCUS GitHub Issue Template](https://docs.google.com/document/d/1KBsn7YfSNrcOxdVOjHKwBsUt_FOQNPzxWMohxs6RWnA/edit?usp=sharing) and converting the `.md` to a `.yml` file. --- .github/ISSUE_TEMPLATE/feedback.yml | 61 +++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/proposal.md | 17 -------- 2 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/feedback.yml delete mode 100644 .github/ISSUE_TEMPLATE/proposal.md diff --git a/.github/ISSUE_TEMPLATE/feedback.yml b/.github/ISSUE_TEMPLATE/feedback.yml new file mode 100644 index 000000000..e37f8fcb7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feedback.yml @@ -0,0 +1,61 @@ +name: FinOps Use Case Feedback +description: Provide feedback on FinOps use cases that cannot be performed with the current FOCUS specification. +title: "[FEEDBACK]: " +labels: ["feedback", "use-case"] +assignees: ["udam-f2"] +body: + - type: markdown + attributes: + value: "The FOCUS working group wants to understand what FinOps use cases cannot be performed today using the current specification so they can be prioritized for upcoming release. Please do not provide any information that may be considered Intellectual Property by any individual or organization." + + - type: input + attributes: + label: Proposed Change + description: Short description of the change and why it is necessary. + placeholder: Describe the proposed change briefly and why it is necessary + validations: + required: true + + - type: textarea + attributes: + label: What FinOps use cases cannot be performed without the proposed change? + description: Describe in detail the current FinOps use cases your organization cannot perform without the proposed change + validations: + required: true + + - type: input + attributes: + label: Which FinOps personas perform this use case? + description: List one or more FinOps personas that perform this use case + placeholder: e.g., Cost Analyst, Cloud Architect, etc + validations: + required: true + + - type: input + attributes: + label: For which providers do you perform this use case for? + description: List each provider separated by commas + placeholder: e.g., AWS, Azure, GCP, Snowflake, etc + validations: + required: true + + - type: dropdown + attributes: + label: Criticality Scale + description: On a scale of 1 - 4, how critical is this for your organization? + options: + - '1: Blocks my organization from adopting FOCUS' + - '2: Important for adoption in the next 3-6 months' + - '3: Important for adoption in the next 6-12 months' + - '4: Suggestion, not planning to use FOCUS soon' + validations: + required: true + + - type: textarea + attributes: + label: Context / Supporting information + description: Provide any other relevant information here + placeholder: Additional details... + validations: + required: true + diff --git a/.github/ISSUE_TEMPLATE/proposal.md b/.github/ISSUE_TEMPLATE/proposal.md deleted file mode 100644 index 539c663fa..000000000 --- a/.github/ISSUE_TEMPLATE/proposal.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Proposal -about: Community proposal to add / enhance the specification -title: "[Proposal] Title for proposal" -labels: proposal -assignees: '' - ---- - -### Type -> Type of issue (e.g. Dimension, Metric, Attribute, Documentation etc.) - -### Proposed Change -> Description of the issue - -### Context / Supporting information ->Description of the issue From 59f7931b43f28209da416794ebd8d08213a1bdfa Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 17 Jan 2024 20:54:05 -0800 Subject: [PATCH 03/65] Update feedback.yml Change the `assignees` value to Maintainers instead of udam-f2 --- .github/ISSUE_TEMPLATE/feedback.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feedback.yml b/.github/ISSUE_TEMPLATE/feedback.yml index e37f8fcb7..a03526af5 100644 --- a/.github/ISSUE_TEMPLATE/feedback.yml +++ b/.github/ISSUE_TEMPLATE/feedback.yml @@ -2,7 +2,7 @@ name: FinOps Use Case Feedback description: Provide feedback on FinOps use cases that cannot be performed with the current FOCUS specification. title: "[FEEDBACK]: " labels: ["feedback", "use-case"] -assignees: ["udam-f2"] +assignees: ["Maintainer"] body: - type: markdown attributes: From c1f03ba4b6e490fef932ba8d3ff3de68def55627 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 17 Jan 2024 21:21:50 -0800 Subject: [PATCH 04/65] Update feedback.yml Assign issue to Maintainers. --- .github/ISSUE_TEMPLATE/feedback.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feedback.yml b/.github/ISSUE_TEMPLATE/feedback.yml index a03526af5..8ec5572b6 100644 --- a/.github/ISSUE_TEMPLATE/feedback.yml +++ b/.github/ISSUE_TEMPLATE/feedback.yml @@ -2,7 +2,7 @@ name: FinOps Use Case Feedback description: Provide feedback on FinOps use cases that cannot be performed with the current FOCUS specification. title: "[FEEDBACK]: " labels: ["feedback", "use-case"] -assignees: ["Maintainer"] +assignees: ["mike-finopsorg,udam-f2"] body: - type: markdown attributes: From fb7271b6237761eeb6de718144f85a6514400c4c Mon Sep 17 00:00:00 2001 From: Christopher Harris Date: Mon, 29 Jan 2024 13:08:55 -0800 Subject: [PATCH 05/65] Fix 'Column required' value to 'True' based on column description #295 (#290) Based on this description, this column should be marked as required ... --- specification/columns/commitmentdiscounttype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/commitmentdiscounttype.md b/specification/columns/commitmentdiscounttype.md index 7b6792139..7611281aa 100644 --- a/specification/columns/commitmentdiscounttype.md +++ b/specification/columns/commitmentdiscounttype.md @@ -21,7 +21,7 @@ A provider-assigned identifier for the type of *commitment-based discount* appli | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | False | +| Column required | True | | Allows nulls | True | | Data type | String | | Value format | \ | From dcc830cc69f1ec7abeef4d74a3f4a205e7b559c6 Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Wed, 31 Jan 2024 10:19:44 -0800 Subject: [PATCH 06/65] Add missing bracket --- specification/columns/subaccountid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/subaccountid.md b/specification/columns/subaccountid.md index c66f24f9e..d3f1b27f1 100644 --- a/specification/columns/subaccountid.md +++ b/specification/columns/subaccountid.md @@ -2,7 +2,7 @@ A Sub Account ID is a provider assigned identifier assigned to a [*sub account*](#glossary:sub-account). Sub account ID is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. -The SubAccountId column MUST be present in the billing data. This column MUST be of type String. If a provider supports a *sub account* construct, that value MUST appear in this column. If a provider does not support a *sub account* construct (only has a *billing account*](#glossary:billing-account)) or does support a *sub account* construct, but the charge does not apply to a *sub account*, the SubAccountId column MUST be null. +The SubAccountId column MUST be present in the billing data. This column MUST be of type String. If a provider supports a *sub account* construct, that value MUST appear in this column. If a provider does not support a *sub account* construct (only has a [*billing account*](#glossary:billing-account)) or does support a *sub account* construct, but the charge does not apply to a *sub account*, the SubAccountId column MUST be null. See [Appendix: Grouping constructs for resources or services](#groupingconstructsforresourcesorservices) for details and examples of the different grouping constructs supported by FOCUS. From 2ddc5669019ed613972ebac9cd2e73d7e27f18e6 Mon Sep 17 00:00:00 2001 From: Irena Jurica Date: Thu, 29 Feb 2024 18:18:44 +0100 Subject: [PATCH 07/65] FOCUS #294: PricingQuantity, PricingUnit, UsageQuantity and UsageUnit review (#324) Multiple Pricing and Usage related columns review: - Usage Quantity - definition adjustment - normative paragraph adjustment - Usage Unit - definition adjustment - normative paragraph adjustment - Pricing Quantity - definition adjustment - Pricing Unit - minor spec adjustment - a discussion regarding the differentiation between PricingUnit and UsageUnit, block-pricing, etc., to be included in the supporting content --------- Co-authored-by: Udam Dewaraja --- specification/columns/pricingquantity.md | 4 ++-- specification/columns/pricingunit.md | 6 +++--- specification/columns/usagequantity.md | 6 +++--- specification/columns/usageunit.md | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/specification/columns/pricingquantity.md b/specification/columns/pricingquantity.md index fa895858f..a2435dec3 100644 --- a/specification/columns/pricingquantity.md +++ b/specification/columns/pricingquantity.md @@ -1,6 +1,6 @@ # Pricing Quantity -The Pricing Quantity represents the volume of a given [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased based on the [Pricing Unit](#pricingunit). Distinct from [Usage Quantity](#usagequantity) (complementary to [Usage Unit](#usageunit)), it focuses on pricing and cost, not *resource* and *service* consumption. +The Pricing Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Pricing Unit](#pricingunit). Distinct from [Usage Quantity](#usagequantity) (complementary to [Usage Unit](#usageunit)), it focuses on pricing and cost, not *resource* and *service* consumption. PricingQuantity MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat). The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric. @@ -14,7 +14,7 @@ Pricing Quantity ## Description -The volume of a given *resource* or *service* used or purchased based on the Pricing Unit. +Volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Pricing Unit. ## Content constraints diff --git a/specification/columns/pricingunit.md b/specification/columns/pricingunit.md index 66a6fd497..26ee4c91f 100644 --- a/specification/columns/pricingunit.md +++ b/specification/columns/pricingunit.md @@ -1,8 +1,8 @@ # Pricing Unit -The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how a provider rates measured usage and purchase quantities considering pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Usage Unit](#usageunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. +The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how a provider rates measured usage and purchase quantities after applying pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Usage Unit](#usageunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. -The PricingUnit column MUST be present in the billing data. This column MUST be of type String. It MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. +The PricingUnit column MUST be present in the billing data. This column MUST be of type String. The value MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The PricingUnit value MUST be semantically equal to the corresponding pricing measurement unit value provided in: @@ -19,7 +19,7 @@ Pricing Unit ## Description -A provider-specified measurement unit for determining unit prices, indicating how a provider rates measured usage and purchase quantities after applying pricing rules like *block pricing*. +Provider-specified measurement unit for determining unit prices, indicating how a provider rates measured usage and purchase quantities after applying pricing rules like *block pricing*. ## Content constraints diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md index f9c6a258b..5efb85d7c 100644 --- a/specification/columns/usagequantity.md +++ b/specification/columns/usagequantity.md @@ -1,8 +1,8 @@ # Usage Quantity -The Usage Quantity represents the volume of a given [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)), and focuses on *resource* and *service* consumption, not pricing and cost. +The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)), and focuses on *resource* and *service* consumption, not pricing and cost. -UsageQuantity MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat). The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT contain null values when [SkuPriceId](#skupriceid) is not null. +UsageQuantity MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat). The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. ## Column ID @@ -14,7 +14,7 @@ Usage Quantity ## Description -Volume of a given *resource* or *service* used or purchased based on the [Usage Unit](#usageunit). +Volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Usage Unit. ## Content constraints diff --git a/specification/columns/usageunit.md b/specification/columns/usageunit.md index b53647360..0939b7ef4 100644 --- a/specification/columns/usageunit.md +++ b/specification/columns/usageunit.md @@ -1,8 +1,8 @@ # Usage Unit -Usage Unit represents the units of a given [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased in combination with [Usage Quantity](#usagequantity). Usage Unit is often listed at a finer granularity or over a different time interval when compared to the [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. +The Usage Unit represents a provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service). Usage Unit complements the [Usage Quantity](#usagequantity) metric. It is often listed at a finer granularity or over a different time interval when compared to the [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. -The UsageUnit column MUST be present in the billing data. This column MUST be of type String and MUST NOT contain null values when the [ChargeCategory](#chargecategory) is "Usage". Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used as the basis for determining values related to any pricing or cost metric. +The UsageUnit column MUST be present in the billing data. This column MUST be of type String. The value MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. ## Column ID @@ -14,7 +14,7 @@ Usage Unit ## Description -Units of a given *resource* or *service* used or purchased in combination with [Usage Quantity](#usagequantity). +Provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a *resource* or *service*. ## Content constraints From bc382fe161f3969703081fc3b752773d0e9341d9 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Thu, 29 Feb 2024 16:51:27 -0500 Subject: [PATCH 08/65] [ADMIN] Add Release planning estimated timeline (#348) On Thursday, Feb 29, the Member's working group approved the following estimated timeline. --------- Co-authored-by: Udam Dewaraja --- RELEASE-PLANNING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 RELEASE-PLANNING.md diff --git a/RELEASE-PLANNING.md b/RELEASE-PLANNING.md new file mode 100644 index 000000000..b0cdb69f2 --- /dev/null +++ b/RELEASE-PLANNING.md @@ -0,0 +1,50 @@ +## Release Planning +This estimated time line was approved by the Members working group on the Feb 29 meeting. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Estimated Timeline v1.0
DateTasksComments
Feb 28 - Mar 11Consistency ReviewOpportunity for everyone to review what has been agreed upon in the working-draft branch.
Lock scope for v1.0.
Mar 12 - Apr 22Drive v1.0 milestone issues to completionIncoming issues will be prioritized by maintainers. Only P0 and some P1 issues will get added to the v1.0 milestone. Prioritization will take voting and comments in issues into consideration
Apr 23 - Apr 30Final Consistency ReviewFreeze working-draft.
Final review, only expecting editorial comments.
May 2Release Candidate Approve by the WG Members
May 2 - May 31IPR ReviewMembers may exclude any Essential Claims from their licensing commitments during this period.
Jun 3Steering Committee Ratifies the Release
Jun 20FinOps X: Onstage FOCUS Adoption stories
From d3ea989a8e2f398a1c59058c61588afb39b9e6f2 Mon Sep 17 00:00:00 2001 From: John Grubb Date: Tue, 5 Mar 2024 11:10:32 -0500 Subject: [PATCH 09/65] Update README, add CONTRIBUTING.md (#346) Fixes https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/issues/345 --- CONTRIBUTING.md | 35 +++++++++++++++++++++++++++++++++++ README.md | 45 +++++++++++++-------------------------------- 2 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..67e26dd9d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing to the FOCUS Specification + +This repository represents the written spec, not working code. As such, most people will not need any development environment - most of the work around the spec happens in regularly scheduled discussions and issues here in Github. If you wish to get involved please see the [FinOps Foundation website](https://focus.finops.org/) and consider [signing the CLA](https://github.com/FinOps-Open-Cost-and-Usage-Spec/EasyCLA). + +Please see the [contribution policy](https://github.com/FinOps-Open-Cost-and-Usage-Spec/foundation/blob/main/contributing.md) for more information. + +## FOCUS Specification Development Environment + +The following is mostly needed by the FinOps Foundation staff members who maintain the FOCUS Repositories and associated document build pipelines. Currently, the only tested (supported) environment is a MacOS setup, however the build pipeline in GitHub uses Ubuntu so should be possible to run on a Linux environment. + +### Setup Steps + +1. Install homebrew (as per: https://brew.sh) +2. Setup cask + + `brew install cask` +3. Install python + + `brew install python` +4. Add packages for python + + `pip3 install -r requirements.txt` +5. Install pandoc and required filter library + + `brew install pandoc` + + `brew install --cask wkhtmltopdf` +6. If your machine does not have git/make etc, you might fun the following: Install developer command line tools for MacOS + + `xcode-select --install` + +### Assembling the specification locally + +1. Move into the `specification` folder +2. Use make to generate the spec `make` diff --git a/README.md b/README.md index 3e5a940f7..fd92a2516 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,18 @@ # FinOps Open Cost and Usage Specification (FOCUS) - Specification Working Group -The Open Cloud Bill working group will develop a common, source-neutral schema of -billing, cost, usage, and observability data mapped to a variety of cloud service provider and SaaS product -sources, with metadata, dimensions, metrics, and measures for the source and common schema fields. As per the [Working Group Charter]() **Link TBC** +## Overview + +The FinOps Open Cost and Usage Specification (FOCUS) is a community-driven effort to develop a standard schema for cloud, SaaS, and other billing data. The primary goal of the FOCUS specification is to make it easier to understand, report on, and manage cloud costs. The FOCUS specification is intended to be adaptable across a variety of cloud service provider and SaaS product sources and defines columns (dimensions and metrics), column-specific requirements, and attributes (spec-wide requirements). This repo also provides supporting content that includes example mappings between well-known provider datasets and what's defined in the FOCUS specification. + +The vision of the FOCUS project is to help the cloud and SaaS industry move toward a common vocabulary around usage and billing data. This will not only help FinOps professionals in the analysis of billing data from disparate sources but will also help software engineering teams by providing a target format for the usage and billing data that their products will generate. + +Some of the usecases this capability can enable: + +- The FOCUS spec will make it easier for FinOps practitioners to approach a new billing data source, as common concepts have been mapped to the common vocabulary of the spec. +- The FOCUS spec will make it easier to merge multiple billing data sources together, and perform cross-cloud and cross-vendor analysis and cost reporting. +- The FOCUS spec should make it easier to open source more FinOps visibility tools, and to accelerate the FinOps framework capability of data ingestion and normalization. + +[Working Group Charter]() **Link TBC** ## Notation Conventions and Compliance @@ -37,32 +47,3 @@ See the [project repository](https://github.com/FinOps-Open-Cost-and-Usage-Spec/ - [Change / contribution process](https://github.com/FinOps-Open-Cost-and-Usage-Spec/foundation/blob/main/contributing.md) -## FOCUS Specification Development Environment - -Most people will not need any development environment, it is mostly needed by the FinOps Foundation staff members who maintain the FOCUS Repositories and associated document build pipelines. Currently, the only tested (supported) environment is a MacOS setup, however the build pipeline in GitHub uses Ubuntu so should be possible to run on a Linux environment. - -### Setup Steps - -1. Install homebrew (as per: https://brew.sh) -2. Setup cask - - `brew install cask` -3. Install python - - `brew install python` -4. Add packages for python - - `pip3 install -r requirements.txt` -5. Install pandoc and required filter library - - `brew install pandoc` - - `brew install --cask wkhtmltopdf` -6. If your machine does not have git/make etc, you might fun the following: Install developer command line tools for MacOS - - `xcode-select --install` - -### Assembling the specification locally - -1. Move into the `specification` folder -2. Use make to generate the spec `make` From 4dfd4f1296f10bafb5a915055065781516ff03fc Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Mon, 11 Mar 2024 13:46:17 -0700 Subject: [PATCH 10/65] Numeric columns should not use 0 when no value (#323) Adding additional clarity to ensure numeric columns do not use `0` in place of a null when there is no value. --------- Co-authored-by: Irena Jurica --- specification/attributes/null_handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/attributes/null_handling.md b/specification/attributes/null_handling.md index 83604d480..4b6a55e1d 100644 --- a/specification/attributes/null_handling.md +++ b/specification/attributes/null_handling.md @@ -20,7 +20,7 @@ Indicates how to handle columns that don't have a value. ## Requirements * Columns MUST use NULL when there isn't a value that can be specified for a nullable column. -* Columns MUST NOT use empty strings or placeholder values such as "Not Set" or "Not Applicable" in columns, regardless of if the column allows nulls or not. +* Columns MUST NOT use empty strings or placeholder values such as 0 for numeric columns or "Not Applicable" for string columns, regardless of whether the column allows nulls or not. ## Exceptions From b9a398279727ed4f5c690b1e04c522ce2ea0dccb Mon Sep 17 00:00:00 2001 From: Ilia Semenov Date: Tue, 12 Mar 2024 11:32:52 -0700 Subject: [PATCH 11/65] Adding Region ID (#352) Region dimension is getting split into 2 dimensions: Region ID and Region Name. This is the change to set up Region ID dimension. --------- Co-authored-by: Sanjna Srivatsa <132018371+SanjnaSrivatsaVMware@users.noreply.github.com> Co-authored-by: Udam Dewaraja Co-authored-by: Christopher Harris Co-authored-by: Larry Advey --- specification/columns/columns.mdpp | 2 +- specification/columns/region.md | 31 ------------------- specification/columns/regionid.md | 31 +++++++++++++++++++ .../columns/{region.md => regionid.md} | 4 +-- 4 files changed, 34 insertions(+), 34 deletions(-) delete mode 100644 specification/columns/region.md create mode 100644 specification/columns/regionid.md rename supporting_content/columns/{region.md => regionid.md} (95%) diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index 6a92737f9..e385fc9d4 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -28,7 +28,7 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "pricingunit.md",1 !INCLUDE "provider.md",1 !INCLUDE "publisher.md",1 -!INCLUDE "region.md",1 +!INCLUDE "regionid.md",1 !INCLUDE "resourceid.md",1 !INCLUDE "resourcename.md",1 !INCLUDE "resourcetype.md",1 diff --git a/specification/columns/region.md b/specification/columns/region.md deleted file mode 100644 index 96fa6ce4b..000000000 --- a/specification/columns/region.md +++ /dev/null @@ -1,31 +0,0 @@ -# Region - -A Region is a provider assigned identifier for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned in or a [*service*](#glossary:service) is provided from. Region is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. - -Region MUST be present in the billing data and MUST be of type String. Region MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region. Region values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. - -## Column ID - -Region - -## Display name - -Region - -## Description - -Isolated geographic area where a *resource* is provisioned in or a *service* is provided from. - -## Content constraints - -| Constraint | Value | -|-----------------|-----------------| -| Column type | Dimension | -| Column required | True | -| Allows nulls | True | -| Data type | String | -| Value format | \ | - -## Introduced (version) - -0.5 diff --git a/specification/columns/regionid.md b/specification/columns/regionid.md new file mode 100644 index 000000000..41e68dd5b --- /dev/null +++ b/specification/columns/regionid.md @@ -0,0 +1,31 @@ +# Region + +A Region ID is a provider-assigned identifier for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. The region is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. + +RegionId MUST be present in the billing data and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region. RegionId values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. + +## Column ID + +RegionId + +## Display name + +Region ID + +## Description + +Provider-assigned identifier for an isolated geographic area where a *resource* is provisioned or a *service* is provided + +## Content constraints + +| Constraint | Value | +|-----------------|-----------------| +| Column type | Dimension | +| Column Required | True | +| Allows nulls | True | +| Data type | String | +| Value format | \ | + +## Introduced (version) + +0.5 diff --git a/supporting_content/columns/region.md b/supporting_content/columns/regionid.md similarity index 95% rename from supporting_content/columns/region.md rename to supporting_content/columns/regionid.md index b7629fe65..8c3cdc6ac 100644 --- a/supporting_content/columns/region.md +++ b/supporting_content/columns/regionid.md @@ -1,4 +1,4 @@ -# Column: Region +# Column: Region ID ## Example provider mappings @@ -42,7 +42,7 @@ Current values observed in billing data for various scenarios: - We had a poll about whether Region should be nullable or not and decided it should. Updated this as part of 1.0. - Definition discussion:\ - "A Region is an isolated geographic area where a resource is provisioned in OR a service is provided from. The region identifier is assigned by the provider. Resources and/or services are commonly utilized from different regions based on considerations for data sovereignty, performance, cost, convenience, or geopolitical reasons. " + "A Region ID is an identifier for an isolated geographic area where a resource is provisioned in OR a service is provided from. The region identifier is assigned by the provider. Resources and/or services are commonly utilized from different regions based on considerations for data sovereignty, performance, cost, convenience, or geopolitical reasons. " | Provider | Provider Region / Location | AZ / Zone | Region Category(?) | Geographical Region (code? Continent) | Country (code?) | TimeZone (check need) | |-----------|----------------------------|------------|--------------------|---------------------------------------|-----------------|-----------------------| From 5dd0ef97c17bff5398a5be3c7ac5b7dac65803aa Mon Sep 17 00:00:00 2001 From: Christopher Harris Date: Thu, 21 Mar 2024 18:06:23 -0400 Subject: [PATCH 12/65] Related to Issue #342 - Tag key differentation when a supporting value can or cannot exist. (#349) Related to Issue: https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/issues/342 Further clarifying tag requirements --------- Co-authored-by: Udam Dewaraja --- specification/columns/tags.md | 11 +++++++---- supporting_content/columns/tags.md | 4 +++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/specification/columns/tags.md b/specification/columns/tags.md index fc6011998..cc65b3743 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -9,7 +9,9 @@ The Tags column adheres to the following requirements: * The Tags column MUST contain user-defined and provider-defined tags. * The Tags column MUST only contain finalized tags. * The Tags column MUST be in [Key-Value Format](#key-valueformat). -* A Tag key without a specified value MUST have its tag value set to null. +* A Tag key with a non-null value for a given resource SHOULD be included in the tags column. +* A Tag key with a null value for a given resource MAY be included in the tags column depending on the provider's tag finalization process. +* A Tag key that does *not* support a corresponding value, sometimes referred to as a *label*, MUST have a corresponding true (boolean) value set. * If Tag finalization is supported, providers MUST publish tag finalization methods and semantics within their respective documentation. * Providers MUST NOT alter user-defined Tag keys or values. @@ -20,12 +22,13 @@ Provider-defined Tags additionally adhere to the following requirements: ## Provider-Defined vs. User-Defined Tags -The following is an example of one user-defined tag and one provider-defined tag, respectively, with tag key, `foo`. The first tag is user-defined and not prefixed. The second tag is provider-defined and prefixed with `acme/`, which the provider has specified as a reserved tag key prefix. +This example illustrates three different tagging scenarios. The first two illustrate when the provider supports both keys and values, while the third is for supporting keys only. The first tag is user-defined and doesn't have a provider prefix. The second tag is provider-defined and has a prefix of `acme/`, which is reserved by the provider. The third tag has a tag key of `baz` and its value is assigned the boolean value `true` since the tag doesn't support a value. ```json { - "foo":"bar", - "acme/foo": "bar" + "foo": "bar", + "acme/foo": "bar", + "baz": true, } ``` diff --git a/supporting_content/columns/tags.md b/supporting_content/columns/tags.md index ed0241269..ab347b3fa 100644 --- a/supporting_content/columns/tags.md +++ b/supporting_content/columns/tags.md @@ -51,4 +51,6 @@ Discussion / Scratch space: - “Custom Tags/Labels”? - One key/value pair for all tags “tags”: [ … ] - Which raw format do we go with? - + - After much discussion and exploring multiple different options, and formats, the following were decided: + - Tags are presented in a json structure - key/value (tags) and key-only (labels) are both included using the same json object. + - Labels will be shown with a value of true (boolean not string). Other options were to break labels out into a separate column, separate part of the JSON object, or provide inline with null OR the boolean - From a05888ce2024633054dc1fc5fa53346281b50680 Mon Sep 17 00:00:00 2001 From: Sanjna Srivatsa <132018371+SanjnaSrivatsaVMware@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:41:53 -0700 Subject: [PATCH 13/65] Creating a new dimension Region Name (#353) Region has now gotten broken into RegionId and RegionName. This is the RegionName portion. --------- Co-authored-by: Christopher Harris Co-authored-by: Udam Dewaraja --- specification/columns/columns.mdpp | 1 + specification/columns/regionid.md | 4 ++-- specification/columns/regionname.md | 31 +++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 specification/columns/regionname.md diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index e385fc9d4..388ca6739 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -29,6 +29,7 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "provider.md",1 !INCLUDE "publisher.md",1 !INCLUDE "regionid.md",1 +!INCLUDE "regionname.md",1 !INCLUDE "resourceid.md",1 !INCLUDE "resourcename.md",1 !INCLUDE "resourcetype.md",1 diff --git a/specification/columns/regionid.md b/specification/columns/regionid.md index 41e68dd5b..558353fbe 100644 --- a/specification/columns/regionid.md +++ b/specification/columns/regionid.md @@ -1,4 +1,4 @@ -# Region +# Region ID A Region ID is a provider-assigned identifier for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. The region is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. @@ -14,7 +14,7 @@ Region ID ## Description -Provider-assigned identifier for an isolated geographic area where a *resource* is provisioned or a *service* is provided +Provider-assigned identifier for an isolated geographic area where a *resource* is provisioned or a *service* is provided. ## Content constraints diff --git a/specification/columns/regionname.md b/specification/columns/regionname.md new file mode 100644 index 000000000..7562c869a --- /dev/null +++ b/specification/columns/regionname.md @@ -0,0 +1,31 @@ +# Region Name + +Region Name is a provider-assigned display name for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. Region Name is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. + +RegionName MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionName MUST be consistent within the provider and MUST be the same value used to indicate the region when provisioning or purchasing the *resource* or *service*. + +## Column ID + +RegionName + +## Display name + +Region Name + +## Description + +The name of an isolated geographic area where a *resource* is provisioned or *service* is provided. + +## Content constraints + +| Constraint | Value | +|-----------------|-----------------| +| Column type | Dimension | +| FOCUS Essential | False | +| Allows nulls | True | +| Data type | String | +| Value format | \| + +## Introduced (version) + +1.0 From ebc8553ae2c099d1eb7271351f2f3e6929dd9d85 Mon Sep 17 00:00:00 2001 From: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:42:50 -0700 Subject: [PATCH 14/65] #343: EffectiveCost clarification (#350) Updating EffectiveCost to be explicit it does not use blended rates. --------- Co-authored-by: Michael Flanakin --- specification/attributes/key_value_format.md | 2 +- specification/columns/effectivecost.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/attributes/key_value_format.md b/specification/attributes/key_value_format.md index baad08cdd..d0ebf6653 100644 --- a/specification/attributes/key_value_format.md +++ b/specification/attributes/key_value_format.md @@ -20,7 +20,7 @@ Rules and formatting requirements for columns appearing in billing data which co * Key-Value Format columns MUST contain a serialized JSON string, consistent with the [ECMA 404](https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf) definition of an object. * Keys in a key-value pair MUST be unique within an object. -* Values in a key-value pair MUST one of the following types: number, string, `true`, `false`, or `null`. +* Values in a key-value pair MUST be one of the following types: number, string, `true`, `false`, or `null`. * Values in a key-value pair MUST NOT be an object nor an array. ## Exceptions diff --git a/specification/columns/effectivecost.md b/specification/columns/effectivecost.md index 85bb80bcd..8e0107033 100644 --- a/specification/columns/effectivecost.md +++ b/specification/columns/effectivecost.md @@ -1,6 +1,6 @@ # Effective Cost -Effective Cost represents a cost inclusive of the impacts of all reduced rates and discounts, augmented with the [*amortization*](#glossary:amortization) of relevant purchases (one-time or recurring) paid to cover future eligible charges. The *amortized* portion included should be proportional to the [Pricing Quantity](#pricingquantity) and the time granularity of the data. This cost is denominated in the [Billing Currency](#billingcurrency). The Effective Cost is commonly utilized to track and analyze spending trends. +Effective Cost represents a cost inclusive of the impacts of all reduced rates and discounts, augmented with the [*amortization*](#glossary:amortization) of relevant purchases (one-time or recurring) paid to cover future eligible charges. The *amortized* portion included should be proportional to the [Pricing Quantity](#pricingquantity) and the time granularity of the data. Effective Cost does not mix or "blend" costs across multiple charges of the same service. This cost is denominated in the [Billing Currency](#billingcurrency). The Effective Cost is commonly utilized to track and analyze spending trends. This column resolves two challenges that are faced by practitioners: From e2cf45655d125d4d9f83896ffd001ae4347e5067 Mon Sep 17 00:00:00 2001 From: SonalGarg-SG <162345708+SonalGarg-SG@users.noreply.github.com> Date: Fri, 22 Mar 2024 12:22:49 -0500 Subject: [PATCH 15/65] Update column_naming_convention.md (#361) Column Name Length suggestion. Issue: https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/issues/362 --------- Co-authored-by: Joaquin Co-authored-by: Shawn Alpay <77511110+salpaysenturus@users.noreply.github.com> Co-authored-by: Udam Dewaraja --- specification/attributes/column_naming_convention.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/specification/attributes/column_naming_convention.md b/specification/attributes/column_naming_convention.md index 2b268e4b1..7140cd468 100644 --- a/specification/attributes/column_naming_convention.md +++ b/specification/attributes/column_naming_convention.md @@ -21,13 +21,14 @@ Naming convention for columns appearing in billing data. * All columns defined by FOCUS MUST follow the following rules: * Column IDs MUST use [Pascal case](https://techterms.com/definition/pascalcase). * Column IDs MUST NOT use abbreviations. - * Column IDs SHOULD NOT use acronyms. * Column IDs MUST be alphanumeric with no special characters. * Columns that have an ID and a Name MUST have the `Id` or `Name` suffix in the Column ID. Display Name for a Column MAY avoid the Name suffix if there are no other columns with the same name prefix. -* Custom (e.g., provider-defined) columns SHOULD follow the same rules as FOCUS columns listed above. -* Columns that have an ID and a Name MUST have the `Id` or `Name` suffix in the Column ID. Display Name for a Column MAY avoid the `Name` suffix if it is considered superfluous. -* Columns with the `Category` suffix must be normalized. + * Column IDs SHOULD NOT use acronyms. + * Column IDs SHOULD NOT exceed 50 characters to accommodate column length restrictions of various data repositories. * All custom columns MUST be prefixed with a consistent `x_` prefix to identify them as external, custom columns and distinguish them from FOCUS columns to avoid conflicts in future releases. +* Columns that have an ID and a Name MUST have the `Id` or `Name` suffix in the Column ID. Display Name for a Column MAY avoid the `Name` suffix if it is considered superfluous. +* Columns with the `Category` suffix MUST be normalized. +* Custom (e.g., provider-defined) columns SHOULD follow the same rules as FOCUS(*) columns listed above. * All FOCUS columns SHOULD be first in the provided dataset. * Custom columns SHOULD be listed after all FOCUS columns and SHOULD NOT be intermixed. * Columns MAY be sorted alphabetically but custom columns SHOULD be after all FOCUS columns. From 3fe51517ef983d5b9ba0beb59386c87392cc2459 Mon Sep 17 00:00:00 2001 From: Udam Dewaraja Date: Thu, 4 Apr 2024 11:36:05 -0700 Subject: [PATCH 16/65] FOCUS feature level introduction - mandatory / conditional / optional (#331) Introduce FOCUS Feature level and some other editorial changes. Co-authored-by: Tim O'Brien Co-authored-by: Alex Hullah Co-authored-by: Michael Flanakin Co-authored-by: Joaquin Co-authored-by: Irena Jurica --- specification/attributes/attributes.mdpp | 2 +- .../attributes/column_naming_convention.md | 2 +- .../attributes/currency_code_format.md | 6 +++--- specification/attributes/datetime_format.md | 4 ++-- specification/attributes/discount_handling.md | 4 ++-- specification/attributes/key_value_format.md | 4 ++-- specification/attributes/null_handling.md | 3 +-- specification/attributes/numeric_format.md | 6 +++--- specification/attributes/unit_format.md | 8 +++---- specification/columns/availabilityzone.md | 10 ++++----- specification/columns/billedcost.md | 8 +++---- specification/columns/billingaccountid.md | 6 +++--- specification/columns/billingaccountname.md | 6 +++--- specification/columns/billingcurrency.md | 6 +++--- specification/columns/billingperiodend.md | 4 ++-- specification/columns/billingperiodstart.md | 4 ++-- specification/columns/chargecategory.md | 9 +++----- specification/columns/chargedescription.md | 4 ++-- specification/columns/chargefrequency.md | 2 +- specification/columns/chargeperiodend.md | 6 +++--- specification/columns/chargeperiodstart.md | 6 +++--- specification/columns/chargesubcategory.md | 6 +++--- .../columns/commitmentdiscountcategory.md | 6 +++--- specification/columns/commitmentdiscountid.md | 6 +++--- .../columns/commitmentdiscountname.md | 6 +++--- .../columns/commitmentdiscounttype.md | 6 +++--- specification/columns/effectivecost.md | 12 +++++------ specification/columns/invoiceissuer.md | 2 +- specification/columns/listcost.md | 14 ++++++------- specification/columns/listunitprice.md | 6 +++--- specification/columns/pricingcategory.md | 12 +++++------ specification/columns/pricingquantity.md | 8 +++---- specification/columns/pricingunit.md | 10 ++++----- specification/columns/provider.md | 5 ++--- specification/columns/publisher.md | 4 ++-- specification/columns/regionid.md | 6 +++--- specification/columns/regionname.md | 12 +++++------ specification/columns/resourceid.md | 10 +++------ specification/columns/resourcename.md | 10 +++------ specification/columns/resourcetype.md | 6 +++--- specification/columns/servicecategory.md | 4 ++-- specification/columns/servicename.md | 2 +- specification/columns/skuid.md | 10 ++++----- specification/columns/skupriceid.md | 10 ++++----- specification/columns/subaccountid.md | 10 ++++----- specification/columns/subaccountname.md | 10 ++++----- specification/columns/tags.md | 9 ++++---- specification/columns/usagequantity.md | 10 ++++----- specification/columns/usageunit.md | 6 +++--- specification/glossary.md | 18 ++++++++-------- specification/overview.md | 21 ++++++++++++------- specification/spec.mdpp | 8 ++++++- 52 files changed, 187 insertions(+), 188 deletions(-) diff --git a/specification/attributes/attributes.mdpp b/specification/attributes/attributes.mdpp index d3050d289..bf6295459 100644 --- a/specification/attributes/attributes.mdpp +++ b/specification/attributes/attributes.mdpp @@ -1,6 +1,6 @@ # Attributes -Attributes are requirements that apply to the billing datasets. Requirements on data content can include naming +Attributes are requirements that apply across a billing dataset instead of an individual column level. Requirements on data content can include naming conventions, data types, formatting standardizations, etc. Attributes may introduce high-level requirements for data granularity, recency, frequency, etc. Requirements defined in attributes are necessary for servicing [FinOps capabilities][FODOFC] accurately using a standard set of instructions regardless of the origin of the data. diff --git a/specification/attributes/column_naming_convention.md b/specification/attributes/column_naming_convention.md index 7140cd468..57fa27527 100644 --- a/specification/attributes/column_naming_convention.md +++ b/specification/attributes/column_naming_convention.md @@ -1,6 +1,6 @@ # Column Naming Convention -Column IDs provided in cost data which follow a consistent naming convention reducing friction for FinOps practitioners that consume the data for analysis, reporting, and other use cases. +Column IDs provided in cost data following a consistent naming convention reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. All columns defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification MUST follow the naming requirements listed below. diff --git a/specification/attributes/currency_code_format.md b/specification/attributes/currency_code_format.md index f69a52135..6e728a497 100644 --- a/specification/attributes/currency_code_format.md +++ b/specification/attributes/currency_code_format.md @@ -1,6 +1,6 @@ # Currency Code Format -Columns that contain currency information in cost data following a consistent format reduces friction for FinOps practitioners that consume the data for analysis, reporting, and other use cases. +Columns that contain currency information in cost data following a consistent format reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. All columns capturing a currency value, defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification, MUST follow the requirements listed below. Custom currency-related columns SHOULD also follow the same formatting requirements. @@ -8,7 +8,7 @@ All columns capturing a currency value, defined in the [FOCUS](#glossary:finops- CurrencyCodeFormat -## Attribute name +## Attribute Name Currency Code Format @@ -18,7 +18,7 @@ Formatting for currency columns appearing in billing data. ## Requirements -* Currency related columns MUST be represented as a three-letter alphabetic code as dictated in the governing document [ISO 4217:2015](https://www.iso.org/standard/64758.html). +Currency-related columns MUST be represented as a three-letter alphabetic code as dictated in the governing document [ISO 4217:2015](https://www.iso.org/standard/64758.html). ## Exceptions diff --git a/specification/attributes/datetime_format.md b/specification/attributes/datetime_format.md index afb41fcd6..4df5623da 100644 --- a/specification/attributes/datetime_format.md +++ b/specification/attributes/datetime_format.md @@ -8,13 +8,13 @@ All columns capturing a date/time value, defined in the [FOCUS](#glossary:finops DateTimeFormat -## Attribute name +## Attribute Name Date/Time Format ## Description -Rules and formatting requirements for date/time related columns appearing in billing data. +Rules and formatting requirements for date/time-related columns appearing in billing data. ## Requirements diff --git a/specification/attributes/discount_handling.md b/specification/attributes/discount_handling.md index c2d20a2eb..06e31ebd9 100644 --- a/specification/attributes/discount_handling.md +++ b/specification/attributes/discount_handling.md @@ -14,7 +14,7 @@ All rows defined in FOCUS MUST follow the discount handling requirements listed DiscountHandling -## Attribute name +## Attribute Name Discount Handling @@ -29,7 +29,7 @@ Indicates how to include and apply discounts to usage charges or rows. * Multiple discounts MAY apply to a row, but they MUST apply to the entire charge covered by that row. * If a discount only applies to a portion of a charge, then the discounted portion of the charge MUST be split into a separate row. * Each discount MUST be identifiable using existing FOCUS columns. - * Rows with a commitment-based discount applied to it MUST include a CommitmentDiscountId. + * Rows with a commitment-based discount applied to them MUST include a CommitmentDiscountId. * If a provider applies a discount that cannot be represented by a FOCUS column, they SHOULD include additional columns to identify the source of the discount. * ChargeSubCategory MUST NOT be null for rows where ChargeType is "Usage" and the row received reduced rates from a discount. * Purchased discounts (e.g., commitment-based discounts) MUST be amortized. diff --git a/specification/attributes/key_value_format.md b/specification/attributes/key_value_format.md index d0ebf6653..478090606 100644 --- a/specification/attributes/key_value_format.md +++ b/specification/attributes/key_value_format.md @@ -14,14 +14,14 @@ Key-Value Format ## Description -Rules and formatting requirements for columns appearing in billing data which convey data as key-value pairs. +Rules and formatting requirements for columns appearing in billing data that convey data as key-value pairs. ## Requirements * Key-Value Format columns MUST contain a serialized JSON string, consistent with the [ECMA 404](https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf) definition of an object. * Keys in a key-value pair MUST be unique within an object. * Values in a key-value pair MUST be one of the following types: number, string, `true`, `false`, or `null`. -* Values in a key-value pair MUST NOT be an object nor an array. +* Values in a key-value pair MUST NOT be an object or an array. ## Exceptions diff --git a/specification/attributes/null_handling.md b/specification/attributes/null_handling.md index 4b6a55e1d..bb309e3ec 100644 --- a/specification/attributes/null_handling.md +++ b/specification/attributes/null_handling.md @@ -1,7 +1,6 @@ # Null Handling -Cost data [*rows*](#glossary:row) that don't have a value that can be presented for a column must be handled in a consistent way to reduce -friction for FinOps practitioners that consume the data for analysis, reporting, and other use cases. +Cost data [*rows*](#glossary:row) that don't have a value that can be presented for a column must be handled in a consistent way to reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. All columns defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification MUST follow the null handling requirements listed below. Custom columns SHOULD also follow the same formatting requirements. diff --git a/specification/attributes/numeric_format.md b/specification/attributes/numeric_format.md index dbaa7fa75..065690c64 100644 --- a/specification/attributes/numeric_format.md +++ b/specification/attributes/numeric_format.md @@ -8,7 +8,7 @@ All columns capturing a numeric value, defined in the FOCUS specification, MUST NumericFormat -## Attribute name +## Attribute Name Numeric Format @@ -19,8 +19,8 @@ Rules and formatting requirements for numeric columns appearing in billing data. ## Requirements * Columns with a Numeric value format MUST contain a single numeric value. -* Numeric values MUST be expressed as an integer value, a decimal values, or a value expressed in scientific notation. Fractional notation MUST NOT be used. -* Numeric values expressed using scientific notation MUST be expressed using E notation "mEn" with a real number m and an integer n indictating a value of "m x 10^n". The sign of the exponent MUST only be expressed as part of the exponent value if n is negative. +* Numeric values MUST be expressed as an integer value, a decimal value, or a value expressed in scientific notation. Fractional notation MUST NOT be used. +* Numeric values expressed using scientific notation MUST be expressed using E notation "mEn" with a real number m and an integer n indicating a value of "m x 10^n". The sign of the exponent MUST only be expressed as part of the exponent value if n is negative. * Numeric values MUST NOT be expressed with mathematical symbols, functions, or operators. * Numeric values MUST NOT contain qualifiers or additional characters (e.g., currency symbols, units of measure, etc.). * Numeric values MUST NOT contain commas or punctuation marks except for a single decimal point (".") if required to express a decimal value. diff --git a/specification/attributes/unit_format.md b/specification/attributes/unit_format.md index cd8761b3d..646b55166 100644 --- a/specification/attributes/unit_format.md +++ b/specification/attributes/unit_format.md @@ -25,12 +25,12 @@ Indicates standards for expressing measurement units in columns appearing in bil * Units MAY be expressed with a unit quantity or time interval. If a unit quantity or time interval is used, the unit quantity or time interval MUST be expressed as a whole number. The following formats are valid: * ` ` - "1000 Tokens", "1000 Characters" * `/ ` - "Units/3 Months" -* Unit values and components of columns using the Unit Format MUST use a capitalization scheme that is consistent with the capitalization scheme used in this attribute, if that term is listed in this section. For example, a value of "gigabyte-seconds" would not be compliant with this specification as the terms "gigabyte" and "second" are listed in this section with the appropriate capitalization. If the unit is not listed in the table, it is to be used over a functional equivalent with similar meaning with the same capitalization scheme. -* Units SHOULD be composed of the list of recommended units listed in this section, unless the unit value covers a *dimension* not listed in the recommended unit set, or if the unit covers a count-based unit distinct from recommended values in the count *dimension* listed in this section. +* Unit values and components of columns using the Unit Format MUST use a capitalization scheme that is consistent with the capitalization scheme used in this attribute if that term is listed in this section. For example, a value of "gigabyte-seconds" would not be compliant with this specification as the terms "gigabyte" and "second" are listed in this section with the appropriate capitalization. If the unit is not listed in the table, it is to be used over a functional equivalent with a similar meaning with the same capitalization scheme. +* Units SHOULD be composed of the list of recommended units listed in this section unless the unit value covers a *dimension* not listed in the recommended unit set, or if the unit covers a count-based unit distinct from recommended values in the count *dimension* listed in this section. ### Data Size Unit Names -Data size unit names MUST be abbreviated using one of abbreviations in the following table. For example, a unit name of "TB" is a valid unit name, and a unit name of "terabyte" is an invalid unit name. Data size abbreviations can be considered both the singular and plural form of the unit. For example, "GB" is both the singular and plural form of the unit "gigabyte", and "GBs" would an invalid unit name. Values that exceed 10^18 MUST use the abbreviation for exabit, exabyte, exbibit, and exbibyte, and values smaller than a byte MUST use the abbreviation for bit or byte. For example, the abbreviation "YB" for "yottabyte" is not a valid data size unit name as it represents a value larger than what is listed in the following table. +Data size unit names MUST be abbreviated using one of the abbreviations in the following table. For example, a unit name of "TB" is a valid unit name, and a unit name of "terabyte" is an invalid unit name. Data size abbreviations can be considered both the singular and plural form of the unit. For example, "GB" is both the singular and plural form of the unit "gigabyte", and "GBs" would be an invalid unit name. Values that exceed 10^18 MUST use the abbreviation for exabit, exabyte, exbibit, and exbibyte, and values smaller than a byte MUST use the abbreviation for bit or byte. For example, the abbreviation "YB" for "yottabyte" is not a valid data size unit name as it represents a value larger than what is listed in the following table. The following table lists the valid abbreviations for data size units from a single bit or byte to 10^18 bits or bytes. @@ -54,7 +54,7 @@ The following table lists the valid abbreviations for data size units from a sin A count-based unit is a noun that represents a discrete number of items, events, or actions. For example, a count-based unit can be used to represent the number of requests, instances, tokens, or connections. -If the following list of recommended values does not cover a count-based unit, a provider MAY introduce a new noun representing a count-based unit. All nouns appearing in unit that are not listed in the recommended values table will be considered count-based units. A new count-based unit value MUST be capitalized. +If the following list of recommended values does not cover a count-based unit, a provider MAY introduce a new noun representing a count-based unit. All nouns appearing in units that are not listed in the recommended values table will be considered count-based units. A new count-based unit value MUST be capitalized. | Count | |:-------------| diff --git a/specification/columns/availabilityzone.md b/specification/columns/availabilityzone.md index d71e04463..503e50aae 100644 --- a/specification/columns/availabilityzone.md +++ b/specification/columns/availabilityzone.md @@ -1,27 +1,27 @@ # Availability Zone -[Availability Zone](#glossary:availability-zone) is a provider assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. Availability Zone is commonly used for scenarios like analyzing cross-zone data transfer usage and the corresponding cost based on where [*resources*](#glossary:resource) are deployed. +An [*availability zone*](#glossary:availability-zone) is a provider-assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. Availability Zone is commonly used for scenarios like analyzing cross-zone data transfer usage and the corresponding cost based on where [*resources*](#glossary:resource) are deployed. -The AvailabilityZone column SHOULD be present in the billing data. This column MUST be of type String and MAY contain null values. +The AvailabilityZone column SHOULD be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. ## Column ID AvailabilityZone -## Display name +## Display Name Availability Zone ## Description -A provider assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. +A provider-assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. ## Content constraints | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | False | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/billedcost.md b/specification/columns/billedcost.md index 9f5c7c66d..942984eb2 100644 --- a/specification/columns/billedcost.md +++ b/specification/columns/billedcost.md @@ -1,14 +1,14 @@ # Billed Cost -The [Billed Cost](#glossary:billed-cost) represents a charge serving as the basis for invoicing, inclusive of the impacts of all reduced rates and discounts while excluding the [*amortization*](#glossary:amortization) of relevant purchases (one-time or recurring) paid to cover future eligible charges. This cost is denominated in the [Billing Currency](#billingcurrency). The Billed Cost is commonly used to perform FinOps capabilities that require cash-basis accounting such as cost allocation, budgeting, and invoice reconciliation. +The [*billed cost*](#glossary:billed-cost) represents a charge serving as the basis for invoicing, inclusive of the impacts of all reduced rates and discounts while excluding the [*amortization*](#glossary:amortization) of relevant purchases (one-time or recurring) paid to cover future eligible charges. This cost is denominated in the [Billing Currency](#billingcurrency). The Billed Cost is commonly used to perform FinOps capabilities that require cash-basis accounting such as cost allocation, budgeting, and invoice reconciliation. -The BilledCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat), and be denominated in the BillingCurrency. The aggregated BilledCost for a [*billing period*](#glossary:billing-period) MUST match the charge received on the invoice for the same *billing period*. +The BilledCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat), and be denominated in the BillingCurrency. The sum of the BilledCost for [*rows*](#glossary:row) in a given [*billing period*](#glossary:billing-period) MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). ## Column ID BilledCost -## Display name +## Display Name Billed Cost @@ -21,7 +21,7 @@ A charge serving as the basis for invoicing, inclusive of all reduced rates and | Constraint | Value | |:----------------|:------------------------| | Column type | Metric | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Decimal | | Value format | [Numeric Format](#numericformat) | diff --git a/specification/columns/billingaccountid.md b/specification/columns/billingaccountid.md index 9f65e7061..cf511607c 100644 --- a/specification/columns/billingaccountid.md +++ b/specification/columns/billingaccountid.md @@ -1,6 +1,6 @@ # Billing Account ID -A Billing Account ID is a provider assigned identifier for a [*billing account*](#glossary:billing-account). *Billing accounts* are commonly used for scenarios like grouping based on organizational constructs, invoice reconciliation and cost allocation strategies. +A Billing Account ID is a provider-assigned identifier for a [*billing account*](#glossary:billing-account). *Billing accounts* are commonly used for scenarios like grouping based on organizational constructs, invoice reconciliation and cost allocation strategies. The BillingAccountId column MUST be present in the billing data. This column MUST be of type String and MUST NOT contain null values. BillingAccountId MUST be a globally unique identifier within a provider. @@ -10,7 +10,7 @@ See [Appendix: Grouping constructs for resources or services](#groupingconstruct BillingAccountId -## Display name +## Display Name Billing Account ID @@ -23,7 +23,7 @@ The identifier assigned to a *billing account* by the provider. | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | \ | diff --git a/specification/columns/billingaccountname.md b/specification/columns/billingaccountname.md index 6c49b3067..32a1b84e4 100644 --- a/specification/columns/billingaccountname.md +++ b/specification/columns/billingaccountname.md @@ -2,7 +2,7 @@ A Billing Account Name is a display name assigned to a [*billing account*](#glossary:billing-account). *Billing accounts* are commonly used for scenarios like grouping based on organizational constructs, invoice reconciliation and cost allocation strategies. -The BillingAccountName column MUST be present in the billing data. This column MUST be of type String. The BillingAccountName MUST NOT be null if a display name can be assigned to a *billing account*. BillingAccountName MUST be unique within a customer when a customer has more than one *billing account*. +The BillingAccountName column MUST be present in the billing data and MUST NOT be null when the provider supports assigning a display name for the *billing account*. This column MUST be of type String. BillingAccountName MUST be unique within a customer when a customer has more than one *billing account*. See [Appendix: Grouping constructs for resources or services](#groupingconstructsforresourcesorservices) for details and examples of the different grouping constructs supported by FOCUS. @@ -10,7 +10,7 @@ See [Appendix: Grouping constructs for resources or services](#groupingconstruct BillingAccountName -## Display name +## Display Name Billing Account Name @@ -23,7 +23,7 @@ The display name assigned to a *billing account*. | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/billingcurrency.md b/specification/columns/billingcurrency.md index 96d3f35a3..df23adb1f 100644 --- a/specification/columns/billingcurrency.md +++ b/specification/columns/billingcurrency.md @@ -1,6 +1,6 @@ # Billing Currency -[Billing Currency](#glossary:billing-currency) is an identifier that represents the currency that a charge for [*resources*](#glossary:resource) or [*services*](#glossary:service) was billed in. Billing Currency is commonly used in scenarios where costs need to be grouped or aggregated. +[*Billing currency*](#glossary:billing-currency) is an identifier that represents the currency that a charge for [*resources*](#glossary:resource) or [*services*](#glossary:service) was billed in. Billing Currency is commonly used in scenarios where costs need to be grouped or aggregated. The BillingCurrency column MUST be present in the billing data. BillingCurrency MUST match the currency used in the invoice generated by the invoice issuer. This column MUST be of type String and MUST NOT contain null values. BillingCurrency MUST conform to [Currency Code Format](#currencycodeformat) requirements. @@ -8,7 +8,7 @@ The BillingCurrency column MUST be present in the billing data. BillingCurrency BillingCurrency -## Display name +## Display Name Billing Currency @@ -21,7 +21,7 @@ Represents the currency that a charge was billed in. | Constraint | Value | |:----------------|:------------------------------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | [Currency Code Format](#currencycodeformat) | diff --git a/specification/columns/billingperiodend.md b/specification/columns/billingperiodend.md index 96bc17adc..a94b09220 100644 --- a/specification/columns/billingperiodend.md +++ b/specification/columns/billingperiodend.md @@ -2,7 +2,7 @@ Billing Period End represents the end date and time of the [*billing period*](#glossary:billing-period). -The BillingPeriodEnd column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. BillingPeriodEnd column MUST conform to [Date/Time Format](#date/timeformat). The sum of the [BilledCost](#billedcost) column for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). +The BillingPeriodEnd column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. BillingPeriodEnd column MUST conform to [Date/Time Format](#date/timeformat) requirements. The sum of the [BilledCost](#billedcost) column for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). ## Column ID @@ -21,7 +21,7 @@ The end date and time of the *billing period*. | Constraint | Value | |:----------------|:-------------------------------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Date/Time | | Value format | [Date/Time Format](#date/timeformat) | diff --git a/specification/columns/billingperiodstart.md b/specification/columns/billingperiodstart.md index dbbb63ab7..c55a3b62a 100644 --- a/specification/columns/billingperiodstart.md +++ b/specification/columns/billingperiodstart.md @@ -2,7 +2,7 @@ Billing Period Start represents the start date and time of the [*billing period*](#glossary:billing-period). -The BillingPeriodStart column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. BillingPeriodStart column MUST conform to [Date/Time Format](#date/timeformat). The sum of the [BilledCost](#billedcost) metric for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). +The BillingPeriodStart column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. BillingPeriodStart column MUST conform to [Date/Time Format](#date/timeformat) requirements. The sum of the [BilledCost](#billedcost) metric for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). ## Column ID @@ -21,7 +21,7 @@ The beginning date and time of the *billing period*. | Constraint | Value | |:----------------|:-------------------------------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Date/Time | | Value format | [Date/Time Format](#date/timeformat) | diff --git a/specification/columns/chargecategory.md b/specification/columns/chargecategory.md index c672dc028..f010bb830 100644 --- a/specification/columns/chargecategory.md +++ b/specification/columns/chargecategory.md @@ -1,11 +1,8 @@ # Charge Category -A Charge Category indicates whether the row represents an upfront or recurring fee, cost of usage that already occurred, -an after-the-fact [*adjustment*](#glossary:adjustment) (e.g., credits), or taxes. The Charge Category is commonly used to identify prepaid purchases -separately from usage-based charges, to separate taxes that may require special handling, or to apply finer-grained -allocation logic to purchases or *adjustments*. +A Charge Category indicates whether the row represents an upfront or recurring fee, cost of usage that already occurred, an after-the-fact [*adjustment*](#glossary:adjustment) (e.g., credits), or taxes. The Charge Category is commonly used to identify prepaid purchases separately from usage-based charges, to separate taxes that may require special handling, or to apply finer-grained allocation logic to purchases or *adjustments*. -The ChargeCategory column MUST be present and MUST NOT be null. This column is of type String and MUST be one of the allowed values. +The ChargeCategory column MUST be present in the billing data and MUST NOT be null. This column is of type String and MUST be one of the allowed values. ## Column ID @@ -24,7 +21,7 @@ Indicates whether the row represents an upfront or recurring fee, cost of usage | Constraint | Value | | :-------------- | :------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | Allowed values | diff --git a/specification/columns/chargedescription.md b/specification/columns/chargedescription.md index 780a46706..2cbdbe6f7 100644 --- a/specification/columns/chargedescription.md +++ b/specification/columns/chargedescription.md @@ -2,7 +2,7 @@ A Charge Description provides a high-level context of a [*row*](#glossary:row) without requiring additional discovery. This column is a self-contained summary of the charge's purpose and price. It typically covers a select group of corresponding details across a billing dataset or provides information not otherwise available. -The Charge Description column MUST be present within the dataset, MUST be of type String, and SHOULD NOT be null. Providers SHOULD specify the length of this column in their publicly available documentation. +The ChargeDescription column MUST be present in the billing data, MUST be of type String, and SHOULD NOT be null. Providers SHOULD specify the length of this column in their publicly available documentation. ## Column ID @@ -21,7 +21,7 @@ Self-contained summary of the charge's purpose and price. | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/chargefrequency.md b/specification/columns/chargefrequency.md index 510d5a975..d0e3b623c 100644 --- a/specification/columns/chargefrequency.md +++ b/specification/columns/chargefrequency.md @@ -21,7 +21,7 @@ Indicates how often a charge will occur. | Constraint | Value | |:----------------|:---------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | Allowed values | diff --git a/specification/columns/chargeperiodend.md b/specification/columns/chargeperiodend.md index 70f8ecd61..94aa07eb6 100644 --- a/specification/columns/chargeperiodend.md +++ b/specification/columns/chargeperiodend.md @@ -2,13 +2,13 @@ Charge Period End represents the end date and time of the [*charge period*](#glossary:chargeperiod). -The ChargePeriodEnd column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. ChargePeriodEnd column MUST conform to [Date/Time Format](#date/timeformat). +The ChargePeriodEnd column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. ChargePeriodEnd column MUST conform to [Date/Time Format](#date/timeformat) requirements. ## Column ID ChargePeriodEnd -## Display name +## Display Name Charge Period End @@ -21,7 +21,7 @@ The end date and time of a *charge period*. | Constraint | Value | |:----------------|:-------------------------------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Date/Time | | Value format | [Date/Time Format](#date/timeformat) | diff --git a/specification/columns/chargeperiodstart.md b/specification/columns/chargeperiodstart.md index e8bca5312..7b53770f8 100644 --- a/specification/columns/chargeperiodstart.md +++ b/specification/columns/chargeperiodstart.md @@ -2,13 +2,13 @@ Charge Period Start represents the starting date and time of the [*charge period*](#glossary:chargeperiod). -The ChargePeriodStart column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. ChargePeriodStart column MUST conform to [Date/Time Format](#date/timeformat). +The ChargePeriodStart column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. ChargePeriodStart column MUST conform to [Date/Time Format](#date/timeformat) requirements. ## Column ID ChargePeriodStart -## Display name +## Display Name Charge Period Start @@ -21,7 +21,7 @@ The beginning date and time of a *charge period*. | Constraint | Value | |:----------------|:-------------------------------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Date/Time | | Value format | [Date/Time Format](#date/timeformat) | diff --git a/specification/columns/chargesubcategory.md b/specification/columns/chargesubcategory.md index 344a69d4e..d8a58866a 100644 --- a/specification/columns/chargesubcategory.md +++ b/specification/columns/chargesubcategory.md @@ -10,11 +10,11 @@ When Charge Category is "Adjustment", the Charge Subcategory indicates what kind ChargeSubcategory MUST follow the requirements listed below: -* The ChargeSubcategory MUST be present in the billing data. +* The ChargeSubcategory column SHOULD be present in the billing data when the provider supports sub-categorization of the [Charge Category](#chargecategory) values. * ChargeSubcategory is of type String and MUST be one of the allowed values. * ChargeSubcategory MUST NOT be null when ChargeCategory is "Usage" and the charge is covered by a *commitment*. * When a usage charge is covered by a *commitment*, ChargeSubcategory MUST be "Used Commitment". - * When a *commitment* is not used fully used or partially used within the committed period, ChargeSubcategory MUST be "Unused Commitment" for the unused usage charge. + * When a *commitment* is not used, fully used, or partially used within the committed period ChargeSubcategory MUST be "Unused Commitment" for the unused usage charge. * ChargeSubcategory MUST be null when ChargeCategory is "Usage" and is not covered by a *commitment*. * ChargeSubcategory MUST NOT be null when ChargeCategory is "Adjustment". * When an *adjustment* applies to a specific item, the corresponding FOCUS columns that identify that item MUST NOT be null and MUST match the applicable item details the *adjustment* pertains to. @@ -37,7 +37,7 @@ Indicates what kind of usage or *adjustment* the *row* represents. | Constraint | Value | | :-------------- | :------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | Allowed values | diff --git a/specification/columns/commitmentdiscountcategory.md b/specification/columns/commitmentdiscountcategory.md index d0e1dfd6c..081887a39 100644 --- a/specification/columns/commitmentdiscountcategory.md +++ b/specification/columns/commitmentdiscountcategory.md @@ -2,13 +2,13 @@ Commitment Discount Category indicates whether the [*commitment-based discount*](#glossary:commitment-based-discount) identified in the CommitmentDiscountId column is based on usage quantity or cost (aka "spend"). -The CommitmentDiscountCategory column MUST be present in the billing data. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. The CommitmentDiscountCategory MUST be one of the allowed values. +The CommitmentDiscountCategory column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. The CommitmentDiscountCategory MUST be one of the allowed values. ## Column ID CommitmentDiscountCategory -## Display name +## Display Name Commitment Discount Category @@ -21,7 +21,7 @@ Indicates whether the *commitment-based discount* identified in the CommitmentDi | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | Allowed Values | diff --git a/specification/columns/commitmentdiscountid.md b/specification/columns/commitmentdiscountid.md index d9f744ab8..f61736b93 100644 --- a/specification/columns/commitmentdiscountid.md +++ b/specification/columns/commitmentdiscountid.md @@ -2,13 +2,13 @@ A Commitment Discount ID is the identifier assigned to a [*commitment-based discount*](#glossary:commitment-based-discount) by the provider. Commitment Discount ID is commonly used for scenarios like chargeback for *commitments* and savings per *commitment-based discount*. -The CommitmentDiscountId column MUST be present in the billing data. This column MUST be of type String and MUST NOT contain null values when a charge is related to a *commitment-based discount*. When a charge is not associated with a *commitment-based discount*, the column MUST be null. CommitmentDiscountId MUST be unique within the provider. +The CommitmentDiscountId column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String and MUST NOT contain null values when a charge is related to a *commitment-based discount*. When a charge is not associated with a *commitment-based discount*, the column MUST be null. CommitmentDiscountId MUST be unique within the provider. ## Column ID CommitmentDiscountId -## Display name +## Display Name Commitment Discount ID @@ -21,7 +21,7 @@ The identifier assigned to a *commitment-based discount* by the provider. | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/commitmentdiscountname.md b/specification/columns/commitmentdiscountname.md index 755d4b57b..282fd8970 100644 --- a/specification/columns/commitmentdiscountname.md +++ b/specification/columns/commitmentdiscountname.md @@ -2,13 +2,13 @@ A Commitment Discount Name is the display name assigned to a [*commitment-based discount*](#glossary:commitment-based-discount). -The CommitmentDiscountName column MUST be present in the billing data. This column MUST be of type String. The CommitmentDiscountName value MUST be null if the charge is not related to a *commitment-based discount* and MAY be null if a display name cannot be assigned to a *commitment-based discount*. CommitmentDiscountName MUST NOT be null if a display name can be assigned to a *commitment-based discount*. +The CommitmentDiscountName column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String. The CommitmentDiscountName value MUST be null if the charge is not related to a *commitment-based discount* and MAY be null if a display name cannot be assigned to a *commitment-based discount*. CommitmentDiscountName MUST NOT be null if a display name can be assigned to a *commitment-based discount*. ## Column ID CommitmentDiscountName -## Display name +## Display Name Commitment Discount Name @@ -21,7 +21,7 @@ The display name assigned to a *commitment-based discount*. | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/commitmentdiscounttype.md b/specification/columns/commitmentdiscounttype.md index 7611281aa..d1417546f 100644 --- a/specification/columns/commitmentdiscounttype.md +++ b/specification/columns/commitmentdiscounttype.md @@ -2,13 +2,13 @@ Commitment Discount Type is a provider-assigned name to identify the type of [*commitment-based discount*](#glossary:commitment-based-discount) applied to the [*row*](#glossary:row). -The CommitmentDiscountType column MUST be present in the billing data. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. Providers MUST use a consistent value-format and a set of values for CommitmentDiscountType values within their billing datasets. +The CommitmentDiscountType column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. Providers MUST use a consistent value format and a set of values for CommitmentDiscountType within their billing datasets. ## Column ID CommitmentDiscountType -## Display name +## Display Name Commitment Discount Type @@ -21,7 +21,7 @@ A provider-assigned identifier for the type of *commitment-based discount* appli | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/effectivecost.md b/specification/columns/effectivecost.md index 8e0107033..4e02fb33d 100644 --- a/specification/columns/effectivecost.md +++ b/specification/columns/effectivecost.md @@ -4,12 +4,12 @@ Effective Cost represents a cost inclusive of the impacts of all reduced rates a This column resolves two challenges that are faced by practitioners: -1. Practitioners need to *amortize* relevant purchases, such as upfront fees, over the duration of the *commitment* and distribute them to the appropriate reporting groups (e.g. [*tags*](#glossary:tag), [*resources*](#glossary:resource)). +1. Practitioners need to *amortize* relevant purchases, such as upfront fees, throughout the *commitment* and distribute them to the appropriate reporting groups (e.g. [*tags*](#glossary:tag), [*resources*](#glossary:resource)). 2. Many [*commitment-based discount*](#glossary:commitment-based-discount) constructs include a recurring expense for the *commitment* for every [*billing period*](#glossary:billing-period) and must distribute this cost to the *resources* using the *commitment*. This forces reconciliation between the initial *commitment* [*row*](#glossary:row) per period and the actual usage *rows*. -The EffectiveCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat), and be denominated in the BillingCurrency. The aggregated EffectiveCost for a billing period MAY NOT match the charge received on the invoice for the same *billing period*. +The EffectiveCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. The aggregated EffectiveCost for a billing period MAY NOT match the charge received on the invoice for the same *billing period*. -In cases where the [SkuPriceId](#skupriceid) is null, the following applies: +In cases where the [ChargeCategory](#chargecategory) is not "Usage" or "Purchase", the following applies: * The EffectiveCost MUST be calculated based on the EffectiveCost of the related charges if the charge is calculated based on other charges (e.g. [ChargeCategory](#chargecategory) is "Tax"). * The EffectiveCost MUST match the [BilledCost](#billedcost) if the charge is unrelated to other charges (e.g. [ChargeSubcategory](#chargesubcategory) is "Credit"). @@ -18,7 +18,7 @@ In cases where the [SkuPriceId](#skupriceid) is null, the following applies: EffectiveCost -## Display name +## Display Name Effective Cost @@ -32,14 +32,14 @@ Providers should distribute the *commitment* purchase amount instead of includin ### Concerning Amortization Approaches -Eligible purchases should be *amortized* using a methodology determined by the provider that reflects the needs of their customer base and is proportional with the Pricing Quantity and the time granularity of the *row*. Should a practitioner desire to *amortize* relevant purchases using a different approach, the practitioner can do so using the [Billed Cost](#billedcost) for the line item representing the initial purchase. +Eligible purchases should be *amortized* using a methodology determined by the provider that reflects the needs of their customer base and is proportional to the Pricing Quantity and the time granularity of the *row*. Should a practitioner desire to *amortize* relevant purchases using a different approach, the practitioner can do so using the [Billed Cost](#billedcost) for the line item representing the initial purchase. ## Content constraints | Constraint | Value | |:----------------|:------------------------| | Column type | Metric | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Decimal | | Value format | [Numeric Format](#numericformat) | diff --git a/specification/columns/invoiceissuer.md b/specification/columns/invoiceissuer.md index b2cfd0d13..a3a4382c4 100644 --- a/specification/columns/invoiceissuer.md +++ b/specification/columns/invoiceissuer.md @@ -25,7 +25,7 @@ The name of the entity responsible for invoicing for the *resources* or *service | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | \ | diff --git a/specification/columns/listcost.md b/specification/columns/listcost.md index 3c415ca2f..3cbbd7d4d 100644 --- a/specification/columns/listcost.md +++ b/specification/columns/listcost.md @@ -1,19 +1,19 @@ # List Cost -List Cost represents the cost calculated by multiplying [List Unit Price](#listunitprice) and the corresponding [Pricing Quantity](#pricingquantity). List Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on various rate optimization activities, by comparing it with [Effective Cost](#effectivecost). +List Cost represents the cost calculated by multiplying the [*list unit price*](#glossary:list-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). List Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on various rate optimization activities, by comparing it with [Billed Cost](#billedcost) and [Effective Cost](#effectivecost). -The ListCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat), and be denominated in the BillingCurrency. When a ListUnitPrice is not null, multiplying the ListUnitPrice by PricingQuantity MUST produce the ListCost. +The ListCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ListUnitPrice](#listunitprice) is present and not null, multiplying the ListUnitPrice by PricingQuantity MUST produce the ListCost. -In cases where the ListUnitPrice is null, the following applies: +In cases where the ListUnitPrice is present and is null, the following applies: -* The ListCost MUST be calculated based on the ListCost of the related charges if the charge is calculated based on other charges (e.g. [ChargeCategory](#chargecategory) is "Tax"). -* The ListCost MUST match the [BilledCost](#billedcost) if the charge is unrelated to other charges (e.g. [ChargeSubcategory](#chargesubcategory) is "Credit"). +* The ListCost of a charge calculated based on other charges (e.g., when the [ChargeCategory](#chargecategory) is "Tax") MUST be calculated based on the ListCost of those related charges. +* The ListCost of a charge unrelated to other charges (e.g., when the [ChargeSubcategory](#chargesubcategory) is "Credit") MUST match the [BilledCost](#billedcost). ## Column ID ListCost -## Display name +## Display Name List Cost @@ -26,7 +26,7 @@ Cost calculated by multiplying List Unit Price and the corresponding Pricing Qua | Constraint | Value | |:----------------|:------------------------| | Column type | Metric | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | Decimal | | Value format | [Numeric Format](#numericformat) | diff --git a/specification/columns/listunitprice.md b/specification/columns/listunitprice.md index f981887df..5de53abad 100644 --- a/specification/columns/listunitprice.md +++ b/specification/columns/listunitprice.md @@ -2,13 +2,13 @@ The List Unit Price represents the suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, exclusive of any discounts. This price is denominated in the [Billing Currency](#billingcurrency). The List Unit Price is commonly used for calculating savings based on various rate optimization activities. -The ListUnitPrice column MUST be present in the billing data. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat), and be denominated in the BillingCurrency. ListUnitPrice MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. When ListUnitPrice is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost). +The ListUnitPrice column SHOULD be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ListUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost). ## Column ID ListUnitPrice -## Display name +## Display Name List Unit Price @@ -21,7 +21,7 @@ The suggested provider-published unit price for a single Pricing Unit of the ass | Constraint | Value | |:----------------|:-------------------------------------| | Column type | Metric | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | Decimal | | Value format | [Numeric Format](#numericformat) | diff --git a/specification/columns/pricingcategory.md b/specification/columns/pricingcategory.md index 7c1bbff37..9cc5701ba 100644 --- a/specification/columns/pricingcategory.md +++ b/specification/columns/pricingcategory.md @@ -1,22 +1,22 @@ # Pricing Category -Pricing Category describes the pricing model used for a charge at the time of use or purchase. It can be useful for distinguishing between charges at the [List Unit Price](#ListUnitPrice) or a reduced price and exposing optimization opportunities, like increasing [commitment-based discount](#glossary:commitment-based-discount) coverage. +Pricing Category describes the pricing model used for a charge at the time of use or purchase. It can be useful for distinguishing between charges incurred at the [*list unit price*](#glossary:list-unit-price) or a reduced price and exposing optimization opportunities, like increasing [commitment-based discount](#glossary:commitment-based-discount) coverage. The PricingCategory column adheres to the following requirements: -* PricingCategory MUST be present in the billing data and MUST be of type String. -* PricingCategory MUST be null if [SkuPriceId](#skupriceid) is null and MUST NOT be null if SkuPriceId is not null. +* PricingCategory SHOULD be present in the billing data when the provider supports more than one pricing category across all SKUs and MUST be of type String. +* PricingCategory MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MUST be null for other ChargeCategory values. * PricingCategory MUST be one of the allowed values. * PricingCategory MUST be "On-Demand" when pricing is predetermined at the standard rate for the [billing account](#glossary:billing-account). * PricingCategory MUST be "Commitment-Based" when [CommitmentDiscountId](#commitmentdiscountid) is not null. * PricingCategory MUST be "Dynamic" when pricing is determined by the provider and may change over time, regardless of predetermined agreement pricing. -* PricingCategory MUST be "Other" when there is a pricing model but none of the current allowed values apply. +* PricingCategory MUST be "Other" when there is a pricing model but none of the allowed values apply. ## Column ID PricingCategory -## Display name +## Display Name Pricing Category @@ -29,7 +29,7 @@ Describes the pricing model used for a charge at the time of use or purchase. | Constraint | Value | | :-------------- | :------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | Allowed values | diff --git a/specification/columns/pricingquantity.md b/specification/columns/pricingquantity.md index a2435dec3..19d2e8e92 100644 --- a/specification/columns/pricingquantity.md +++ b/specification/columns/pricingquantity.md @@ -2,26 +2,26 @@ The Pricing Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Pricing Unit](#pricingunit). Distinct from [Usage Quantity](#usagequantity) (complementary to [Usage Unit](#usageunit)), it focuses on pricing and cost, not *resource* and *service* consumption. -PricingQuantity MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat). The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric. +The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric. ## Column ID PricingQuantity -## Display name +## Display Name Pricing Quantity ## Description -Volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Pricing Unit. +The volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Pricing Unit. ## Content constraints | Constraint | Value | |:----------------|:--------------------------| | Column type | Metric | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | True | | Data type | Decimal | | Value format | [Numeric Format](#numericformat) | diff --git a/specification/columns/pricingunit.md b/specification/columns/pricingunit.md index 26ee4c91f..67f89aae3 100644 --- a/specification/columns/pricingunit.md +++ b/specification/columns/pricingunit.md @@ -1,8 +1,8 @@ # Pricing Unit -The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how a provider rates measured usage and purchase quantities after applying pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Usage Unit](#usageunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. +The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how the provider rates measured usage and purchase quantities after applying pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Usage Unit](#usageunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. -The PricingUnit column MUST be present in the billing data. This column MUST be of type String. The value MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. +The PricingUnit column MUST be present in the billing data. This column MUST be of type String. This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The PricingUnit value MUST be semantically equal to the corresponding pricing measurement unit value provided in: @@ -13,20 +13,20 @@ The PricingUnit value MUST be semantically equal to the corresponding pricing me PricingUnit -## Display name +## Display Name Pricing Unit ## Description -Provider-specified measurement unit for determining unit prices, indicating how a provider rates measured usage and purchase quantities after applying pricing rules like *block pricing*. +Provider-specified measurement unit for determining unit prices, indicating how the provider rates measured usage and purchase quantities after applying pricing rules like *block pricing*. ## Content constraints | Constraint | Value | |-----------------|-------------------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | True | | Data type | String | | Value format | [Unit Format](#unitformat) | diff --git a/specification/columns/provider.md b/specification/columns/provider.md index 88788d65b..ff772f70c 100644 --- a/specification/columns/provider.md +++ b/specification/columns/provider.md @@ -1,7 +1,6 @@ # Provider -A Provider is an entity that made the [*resources*](#glossary:resource) or [*services*](#glossary:service) available for purchase. It is commonly used for cost -analysis and reporting scenarios. +A Provider is an entity that makes the [*resources*](#glossary:resource) or [*services*](#glossary:service) available for purchase. It is commonly used for cost analysis and reporting scenarios. The Provider column MUST be present in the billing data. This column MUST be of type String and MUST NOT contain null values. @@ -25,7 +24,7 @@ The name of the entity that made the *resources* or *services* available for pur | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | \ | diff --git a/specification/columns/publisher.md b/specification/columns/publisher.md index f29c62bcf..827b19014 100644 --- a/specification/columns/publisher.md +++ b/specification/columns/publisher.md @@ -1,6 +1,6 @@ # Publisher -A Publisher is an entity that produced the [*resources*](#glossary:resource) or [*services*](#glossary:service) that were purchased. It is commonly used for cost analysis and reporting scenarios. +A Publisher is an entity that produces the [*resources*](#glossary:resource) or [*services*](#glossary:service) that were purchased. It is commonly used for cost analysis and reporting scenarios. The Publisher column MUST be present in the billing data. This column MUST be of type String and MUST NOT contain null values. @@ -24,7 +24,7 @@ The name of the entity that produced the *resources* or *services* that were pur | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | \ | diff --git a/specification/columns/regionid.md b/specification/columns/regionid.md index 558353fbe..f751b71e6 100644 --- a/specification/columns/regionid.md +++ b/specification/columns/regionid.md @@ -2,13 +2,13 @@ A Region ID is a provider-assigned identifier for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. The region is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. -RegionId MUST be present in the billing data and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region. RegionId values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. +The RegionId column SHOULD be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionId values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. ## Column ID RegionId -## Display name +## Display Name Region ID @@ -21,7 +21,7 @@ Provider-assigned identifier for an isolated geographic area where a *resource* | Constraint | Value | |-----------------|-----------------| | Column type | Dimension | -| Column Required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/regionname.md b/specification/columns/regionname.md index 7562c869a..03f389f0d 100644 --- a/specification/columns/regionname.md +++ b/specification/columns/regionname.md @@ -2,30 +2,30 @@ Region Name is a provider-assigned display name for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. Region Name is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. -RegionName MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionName MUST be consistent within the provider and MUST be the same value used to indicate the region when provisioning or purchasing the *resource* or *service*. +The RegionName column SHOULD be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionName values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. ## Column ID RegionName -## Display name +## Display Name Region Name ## Description -The name of an isolated geographic area where a *resource* is provisioned or *service* is provided. +The name of an isolated geographic area where a *resource* is provisioned or a *service* is provided. ## Content constraints | Constraint | Value | |-----------------|-----------------| | Column type | Dimension | -| FOCUS Essential | False | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | -| Value format | \| +| Value format | \ | ## Introduced (version) -1.0 +0.5 diff --git a/specification/columns/resourceid.md b/specification/columns/resourceid.md index 1a22e18bf..c4b1ab06c 100644 --- a/specification/columns/resourceid.md +++ b/specification/columns/resourceid.md @@ -1,12 +1,8 @@ # Resource ID -A Resource ID is an identifier assigned to a [*resource*](#glossary:resource) by the provider. The Resource ID is commonly used for cost -reporting, analysis, and allocation scenarios. +A Resource ID is an identifier assigned to a [*resource*](#glossary:resource) by the provider. The Resource ID is commonly used for cost reporting, analysis, and allocation scenarios. -The ResourceId column MUST be present in the billing data. This column MUST be of type String. The ResourceId value -MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource*. ResourceId MUST appear in the -cost data if an identifier is assigned to a *resource* by the provider. ResourceId SHOULD be a fully-qualified -identifier that ensures global uniqueness within the provider. +The ResourceId column SHOULD be present in the billing data when the provider supports billing based on provisioned resources. This column MUST be of type String. The ResourceId value MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource*. ResourceId MUST appear in the cost data if an identifier is assigned to a *resource* by the provider. ResourceId SHOULD be a fully-qualified identifier that ensures global uniqueness within the provider. ## Column ID @@ -25,7 +21,7 @@ Identifier assigned to a *resource* by the provider. | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/resourcename.md b/specification/columns/resourcename.md index fd304cbbd..0d44855cf 100644 --- a/specification/columns/resourcename.md +++ b/specification/columns/resourcename.md @@ -1,12 +1,8 @@ # Resource Name -The Resource Name is a display name assigned to a [*resource*](#glossary:resource). It is commonly used for cost analysis, reporting, and -allocation scenarios. +The Resource Name is a display name assigned to a [*resource*](#glossary:resource). It is commonly used for cost analysis, reporting, and allocation scenarios. -The ResourceName column MUST be present in the billing data. This column MUST be of type String. The ResourceName value -MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource* or because a display name cannot -be assigned to a *resource*. ResourceName MUST NOT be null if a display name can be assigned to a *resource*. *Resources* not -provisioned interactively or only have a system generated [ResourceId](#resourceid) MUST NOT duplicate the same value as the ResourceName. +The ResourceName column SHOULD be present in the billing data when the provider supports billing based on provisioned resources. This column MUST be of type String. The ResourceName value MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource* or because a display name cannot be assigned to a *resource*. ResourceName MUST NOT be null if a display name can be assigned to a *resource*. *Resources* not provisioned interactively or only have a system-generated [ResourceId](#resourceid) MUST NOT duplicate the same value as the ResourceName. ## Column ID @@ -25,7 +21,7 @@ Display name assigned to a *resource*. | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/resourcetype.md b/specification/columns/resourcetype.md index 7fd2741e7..2931ca3ef 100644 --- a/specification/columns/resourcetype.md +++ b/specification/columns/resourcetype.md @@ -1,8 +1,8 @@ # Resource Type -Resource Type describes the kind of [*resource*](#glossary:resource) the charge applies to. A Resource Type is commonly used for scenarios like identifying cost changes in groups of similar *resources* and may include values like Virtual Machine, Data Warehouse, and Load Balancer. +Resource Type describes the kind of [*resource*](#glossary:resource) the charge applies to. A Resource Type is commonly used for scenarios like identifying cost changes in groups of similar *resources* and may include values like Virtual Machine, Data Warehouse, and Load Balancer. -The ResourceType column MUST be present within billing data. This column MUST be of type String and MUST NOT be null when a corresponding [ResourceId](#resourceid) is not null. When a corresponding ResourceId value is null, the ResourceType column value MUST also be null. Providers MUST use a consistent value-format and a set of values for ResourceType values within their billing datasets. +The ResourceType column SHOULD be present in the billing data when the provider supports billing based on provisioned resources and supports assigning a type for resources. This column MUST be of type String and MUST NOT be null when a corresponding [ResourceId](#resourceid) is not null. When a corresponding ResourceId value is null, the ResourceType column value MUST also be null. Providers MUST use a consistent value format and a set of values for ResourceType values within their billing datasets. ## Column ID @@ -21,7 +21,7 @@ The kind of *resource* the charge applies to. | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/servicecategory.md b/specification/columns/servicecategory.md index 8dde3462d..1ee72a960 100644 --- a/specification/columns/servicecategory.md +++ b/specification/columns/servicecategory.md @@ -1,6 +1,6 @@ # Service Category -The Service Category is the highest-level classification of a [*service*](#glossary:service) based on the core function of the *service*. Each *service* should have one and only one category that best aligns to its primary purpose. The Service Category is commonly used for scenarios like analyzing costs across providers and tracking the migration of workloads across fundamentally different architectures. +The Service Category is the highest-level classification of a [*service*](#glossary:service) based on the core function of the *service*. Each *service* should have one and only one category that best aligns with its primary purpose. The Service Category is commonly used for scenarios like analyzing costs across providers and tracking the migration of workloads across fundamentally different architectures. The ServiceCategory column MUST be present and MUST NOT be null. This column is of type String and MUST be one of the allowed values. @@ -21,7 +21,7 @@ Highest-level classification of a *service* based on the core function of the *s | Constraint | Value | | :-------------- | :------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | Allowed Values | diff --git a/specification/columns/servicename.md b/specification/columns/servicename.md index 3982f940c..0f4ab9547 100644 --- a/specification/columns/servicename.md +++ b/specification/columns/servicename.md @@ -23,7 +23,7 @@ An offering that can be purchased from a provider (e.g., cloud virtual machine, | Constraint | Value | | :-------------- | :--------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | \ | diff --git a/specification/columns/skuid.md b/specification/columns/skuid.md index faa48ade1..f8988d685 100644 --- a/specification/columns/skuid.md +++ b/specification/columns/skuid.md @@ -1,27 +1,27 @@ # SKU ID -A SKU ID is an unique identifier that defines a provider-supported construct for organizing properties that are common across one or more [*SKU Prices*](#glossary:sku-price). SKU ID can be referenced on a catalog or [*price list*](#glossary:price-list) published by a provider to look up detailed information about the SKU. The composition of the properties associated with the SKU ID may differ across providers. Some providers may not support the [*SKU*](#glossary:sku) construct and instead associate all such properties directly with the *SKU Price*. SKU ID is commonly used for analyzing cost based on *SKU* related properties above the pricing constructs. +A SKU ID is a unique identifier that defines a provider-supported construct for organizing properties that are common across one or more [*SKU Prices*](#glossary:sku-price). SKU ID can be referenced on a catalog or [*price list*](#glossary:price-list) published by a provider to look up detailed information about the SKU. The composition of the properties associated with the SKU ID may differ across providers. Some providers may not support the [*SKU*](#glossary:sku) construct and instead associate all such properties directly with the *SKU Price*. SKU ID is commonly used for analyzing cost based on *SKU*-related properties above the pricing constructs. -The SkuId column MUST be present in the billing data. This column MUST be of type String. The SkuId MUST NOT be null when [SkuPriceId](#skupriceid) is not null. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. +The SkuId column SHOULD be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. The SkuId MUST NOT be null when [SkuPriceId](#skupriceid) is not null. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. ## Column ID SkuId -## Display name +## Display Name SKU ID ## Description -An unique identifier that defines a provider-supported construct for organizing properties that are common across one or more *SKU Prices*. +A unique identifier that defines a provider-supported construct for organizing properties that are common across one or more *SKU Prices*. ## Content constraints | Constraint | Value | | :-------------- | :--------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index b27fc5bef..a1830260f 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -2,29 +2,29 @@ A SKU Price ID is a unique identifier that defines the unit price used to calculate the charge. SKU Price ID can be referenced on a [*price list*](#glossary:price-list) published by a provider to look up detailed information, including a corresponding list unit price. The composition of the properties associated with the SKU Price ID may differ across providers. SKU Price ID is commonly used for analyzing cost based on pricing properties such as Terms and Tiers. -The SkuPriceId column MUST be present in the billing data. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage". SkuPriceId MUST NOT be null when [ChargeSubcategory](#chargesubcategory) is "Refund" and the refund is related to charges with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. +The SkuPriceId column SHOULD be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider-published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage". SkuPriceId MUST NOT be null when [ChargeSubcategory](#chargesubcategory) is "Refund" and the refund is related to charges with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. ## Column ID SkuPriceId -## Display name +## Display Name SKU Price ID ## Description -Unique identifier that defines the unit price used to calculate the charge. +A unique identifier that defines the unit price used to calculate the charge. ## Content constraints | Constraint | Value | | :--------------- | :------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | -| Value format | \ | +| Value format | \ | ## Introduced (version) diff --git a/specification/columns/subaccountid.md b/specification/columns/subaccountid.md index d3f1b27f1..53df2f73b 100644 --- a/specification/columns/subaccountid.md +++ b/specification/columns/subaccountid.md @@ -1,8 +1,8 @@ # Sub Account ID -A Sub Account ID is a provider assigned identifier assigned to a [*sub account*](#glossary:sub-account). Sub account ID is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. +A Sub Account ID is a provider-assigned identifier assigned to a [*sub account*](#glossary:sub-account). Sub Account ID is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. -The SubAccountId column MUST be present in the billing data. This column MUST be of type String. If a provider supports a *sub account* construct, that value MUST appear in this column. If a provider does not support a *sub account* construct (only has a [*billing account*](#glossary:billing-account)) or does support a *sub account* construct, but the charge does not apply to a *sub account*, the SubAccountId column MUST be null. +The SubAccountId column SHOULD be present in the billing data when the provider supports a *sub account* construct. This column MUST be of type String. If a charge does not apply to a *sub account*, the SubAccountId column MUST be null. See [Appendix: Grouping constructs for resources or services](#groupingconstructsforresourcesorservices) for details and examples of the different grouping constructs supported by FOCUS. @@ -10,20 +10,20 @@ See [Appendix: Grouping constructs for resources or services](#groupingconstruct SubAccountId -## Display name +## Display Name Sub Account ID ## Description -An ID assigned to a grouping of *resources* or *services*, often used to manage access and/or cost. +An ID assigned to a grouping of [*resources*](#glossary:resource) or [*services*](#glossary:service), often used to manage access and/or cost. ## Content constraints | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/subaccountname.md b/specification/columns/subaccountname.md index f3905028d..f0c636811 100644 --- a/specification/columns/subaccountname.md +++ b/specification/columns/subaccountname.md @@ -1,8 +1,8 @@ # Sub Account Name -A sub account name is a display name assigned to a *sub account*. Sub account Name is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. +A Sub Account Name is a display name assigned to a [*sub account*](#glossary:sub-account). Sub account Name is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. -The SubAccountName column MUST be present in the billing data. This column MUST be of type String. If a provider supports setting a display name for *sub accounts*, that value MUST appear in this column. If a provider does not support a *sub account* construct (only has a [*billing account*](#glossary:billing-account)) or does support a *sub account* construct, but the charge does not apply to a *sub account*, the SubAccountName column MUST be null. +The SubAccountName column SHOULD be present in the billing data when the provider supports a *sub account* construct. This column MUST be of type String. If a charge does not apply to a *sub account*, the SubAccountName column MUST be null. See [Appendix: Grouping constructs for resources or services](#groupingconstructsforresourcesorservices) for details and examples of the different grouping constructs supported by FOCUS. @@ -10,20 +10,20 @@ See [Appendix: Grouping constructs for resources or services](#groupingconstruct SubAccountName -## Display name +## Display Name Sub Account Name ## Description -A name assigned to a grouping of *resources* or *services*, often used to manage access and/or cost. +A name assigned to a grouping of [*resources*](#glossary:resource) or [*services*](#glossary:service), often used to manage access and/or cost. ## Content constraints | Constraint | Value | |:----------------|:----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/tags.md b/specification/columns/tags.md index cc65b3743..788f59cfe 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -6,6 +6,7 @@ A tag becomes [*finalized*](#glossary:finalized-tag) when a single value is sele The Tags column adheres to the following requirements: +* The Tags column SHOULD be present in the billing data when the provider supports setting user or provider-defined tags. * The Tags column MUST contain user-defined and provider-defined tags. * The Tags column MUST only contain finalized tags. * The Tags column MUST be in [Key-Value Format](#key-valueformat). @@ -34,9 +35,9 @@ This example illustrates three different tagging scenarios. The first two illust ## Finalized Tags -Within a provider, tag keys may be associated with multiple values, and potentially defined at different levels within the provider, such as accounts, folders, [*resource*](#glossary:resource) and other *resource* grouping constructs. When finalizing, *providers* must reduce these multiple levels of definition to a single value where each key is associated with exactly one value. The method by which this is done and the semantics are up to each provider, but must be documented within their respective documentation. +Within a provider, tag keys may be associated with multiple values, and potentially defined at different levels within the provider, such as accounts, folders, [*resource*](#glossary:resource) and other *resource* grouping constructs. When finalizing, *providers* must reduce these multiple levels of definition to a single value where each key is associated with exactly one value. The method by which this is done and the semantics are up to each provider but must be documented within their respective documentation. -As a example, let's assume 1 [*sub account*](#glossary:sub-account) exists with 1 virtual machine with the following details, and tag inheritance favors Resources over *Sub Accounts*. +As an example, let's assume 1 [*sub account*](#glossary:sub-account) exists with 1 virtual machine with the following details, and tag inheritance favors Resources over *Sub Accounts*. * Sub Account * id: *my-sub-account* @@ -64,14 +65,14 @@ Tags ## Description -The set of tags assigned to *tag sources* that also account for potential provider-defined or user-defined tag evaluations. +The set of tags assigned to *tag sources* that account for potential provider-defined or user-defined tag evaluations. ## Content Constraints | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | JSON | | Value format | [Key-Value Format](#key-valueformat) | diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md index 5efb85d7c..7ab85ea9e 100644 --- a/specification/columns/usagequantity.md +++ b/specification/columns/usagequantity.md @@ -1,27 +1,27 @@ # Usage Quantity -The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)), and focuses on *resource* and *service* consumption, not pricing and cost. +The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)) and focuses on *resource* and *service* consumption, not pricing and cost. -UsageQuantity MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat). The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. +UsageQuantity column SHOULD be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. ## Column ID UsageQuantity -## Display name +## Display Name Usage Quantity ## Description -Volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Usage Unit. +The volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Usage Unit. ## Content constraints | Constraint | Value | |:----------------|:--------------| | Column type | Metric | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | Decimal | | Value format | [Numeric Format](#numericformat) | diff --git a/specification/columns/usageunit.md b/specification/columns/usageunit.md index 0939b7ef4..171cd2f69 100644 --- a/specification/columns/usageunit.md +++ b/specification/columns/usageunit.md @@ -2,13 +2,13 @@ The Usage Unit represents a provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service). Usage Unit complements the [Usage Quantity](#usagequantity) metric. It is often listed at a finer granularity or over a different time interval when compared to the [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. -The UsageUnit column MUST be present in the billing data. This column MUST be of type String. The value MUST NOT be null if [SkuPriceId](#skupriceid) is not null and MUST be null if SkuPriceId is null. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. +The UsageUnit column SHOULD be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. UsageUnit MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. ## Column ID UsageUnit -## Display name +## Display Name Usage Unit @@ -21,7 +21,7 @@ Provider-specified measurement unit indicating how a provider measures usage or | Constraint | Value | |:----------------|:----------------| | Column type | Metric | -| Column required | True | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | [Unit Format](#unitformat) recommended | diff --git a/specification/glossary.md b/specification/glossary.md index 05b138b32..36f15dfea 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -2,7 +2,7 @@ Adjustment -A charge representing a modification to billing data to account for certain events or circumstances not previously captured, or captured incorrectly. Examples include: billing errors, service disruptions, or pricing changes. +A charge representing a modification to billing data to account for certain events or circumstances not previously captured, or captured incorrectly. Examples include billing errors, service disruptions, or pricing changes. Amortization @@ -10,7 +10,7 @@ The distribution of upfront costs over time to accurately reflect the consumptio Availability Zone -A collection of geographically-separated locations containing a data center or cluster of data centers. Each availability zone (AZ) should have its own power, cooling, and networking, to provide redundancy and fault tolerance. +A collection of geographically separated locations containing a data center or cluster of data centers. Each availability zone (AZ) should have its own power, cooling, and networking, to provide redundancy and fault tolerance. Billed Cost @@ -34,7 +34,7 @@ The time window that an organization receives an invoice for, inclusive of the s Charge -A row in a FOCUS compatible cost and usage dataset. +A row in a FOCUS-compatible cost and usage dataset. Charge Period @@ -66,7 +66,7 @@ A tag with one tag value chosen from a set of possible tag values after being pr FinOps Cost and Usage Specification (FOCUS) -An open source specification that defines requirements for billing data. +An open-source specification that defines requirements for billing data. Interruptible @@ -74,17 +74,17 @@ A category of compute resources that can be paused or terminated by the CSP with List Unit Price -The suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, exclusive of any discounts. This price is denominated in the [Billing Currency](#glossary:billingcurrency). +The suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated [SKU](#glossary:sku), exclusive of any discounts. This price is denominated in the [Billing Currency](#glossary:billingcurrency). Metric -A FOCUS defined column that provides numeric values, allowing for aggregation operations such as arithmetic operations (sum, multiplication, averaging etc.) and statistical operations. +A FOCUS-defined column that provides numeric values, allowing for aggregation operations such as arithmetic operations (sum, multiplication, averaging etc.) and statistical operations. Managed Service Provider (MSP) A company or organization that provides outsourced management and support of a range of IT services, such as network infrastructure, cybersecurity, cloud computing, and more. -On Demand +On-Demand A term that describes a service that is available and provided immediately or as needed, without requiring a pre-scheduled appointment or prior arrangement. In Cloud Computing, virtual machines can be created and terminated as needed, i.e. on demand. @@ -106,7 +106,7 @@ A unique component that incurs a charge. Row -A row in a FOCUS compatible cost and usage dataset. +A row in a FOCUS-compatible cost and usage dataset. Service @@ -118,7 +118,7 @@ A construct composed of the common properties of a product offering associated w SKU Price -The unit price used to calculate a charge that is associated to one SKU. SKU Prices are usually referenced from provider's price list and unique to various providers. +The unit price used to calculate a charge that is associated with one SKU. SKU Prices are usually referenced from the provider's price list and are unique to various providers. Sub Account diff --git a/specification/overview.md b/specification/overview.md index e4fc5618c..c98a3e35d 100644 --- a/specification/overview.md +++ b/specification/overview.md @@ -2,9 +2,9 @@ *This section is non-normative.* -FOCUS aims to establish a community-driven specification for consumption-based billing data. Due to the lack of a broadly adopted specification, infrastructure and services [*providers*](#glossary:provider) have resorted to proprietary billing schemas and terminology. However, the lack of conformance amongst the billing data generators has forced FinOps practitioners to employ disparate, best-effort schemes which each *practitioner* must develop individually for each *provider* in order to perform essential FinOps capabilities such as chargeback, cost allocation, budgeting and forecasting. +FOCUS aims to establish a community-driven specification for consumption-based billing data. Due to the lack of a broadly adopted specification, infrastructure and services [*providers*](#glossary:provider) have resorted to proprietary billing schemas and terminology. The lack of conformance amongst the billing data generators has forced FinOps practitioners to employ disparate, best-effort schemes which each *practitioner* must develop individually for each *provider* to perform essential FinOps capabilities such as chargeback, cost allocation, budgeting and forecasting. -The FOCUS specification's schema definition and FinOps aligned terminology provide a clear guide for producing FinOps-serviceable billing datasets. Datasets conforming to FOCUS enable FinOps practitioners to perform common FinOps capabilities, like the ones mentioned above, using a generic set of instructions, regardless of the origin of the dataset. +The FOCUS specification's schema definition and FinOps-aligned terminology provide a clear guide for producing FinOps-serviceable billing datasets. Datasets conforming to FOCUS enable FinOps practitioners to perform common FinOps capabilities, like the ones mentioned above, using a generic set of instructions, regardless of the origin of the dataset. ## Background and History @@ -32,11 +32,11 @@ The following principles were considered while building the specification. ### FOCUS is an iterative, living specification -* Incremental iterations of the specification released on a regular basis will provide higher value to practitioners and allow feedback as the specification develops. The goal is not to get to a complete, finished specification in one pass. +* Incremental iterations of the specification released regularly will provide higher value to practitioners and allow feedback as the specification develops. The goal is not to get to a complete, finished specification in one pass. -### Working backwards with ease of adoption +### Working backward with ease of adoption -* Aim to work backwards from essential FinOps capabilities that practitioners need to perform to prioritize the dimensions, metrics and the attributes of the cost and usage data that should be defined in the specification to fulfill that capability. +* Aim to work backward from essential FinOps capabilities that practitioners need to perform to prioritize the dimensions, metrics and attributes of the cost and usage data that should be defined in the specification to fulfill that capability. * Be FinOps scenario-driven. Define columns that answer scenario questions; don't look for scenarios to fit a column, each column must have a use case. * Don't add dimensions or metrics to the specification just because it can be added. * When defining the specification, consideration should be made to existing data already in the major providers' (AWS, GCP, Azure, OCI) datasets. @@ -51,7 +51,7 @@ The following principles were considered while building the specification. * While the schema, naming, terminology, and attributes of many providers are reviewed during development, this specification aims to be provider-neutral. * Contributors must take care to ensure the specification examines how each decision relates to each of the major cloud providers and SaaS vendors, not favoring any single one. -* In some cases, the approach may closely resemble one or more provider's implementation, while in other cases, the approach might be new. In all cases, the FOCUS group (community composed of FinOps practitioners, Cloud and SaaS providers and FinOps vendors) will attempt to prioritize alignment with the FinOps [Framework][FODOF] and [Capabilities][FODOFC]. +* In some cases, the approach may closely resemble one or more provider's implementations, while in other cases, the approach might be new. In all cases, the FOCUS group (community composed of FinOps practitioners, Cloud and SaaS providers and FinOps vendors) will attempt to prioritize enabling FinOps [Capabilities][FODOFC] and alignment with the FinOps [Framework][FODOF]. ### Extensibility @@ -77,8 +77,13 @@ The following principles were considered while building the specification. The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this specification are to be interpreted as described in [BCP14](https://tools.ietf.org/html/bcp14) [[RFC2119](https://tools.ietf.org/html/rfc2119)][[RFC8174](https://tools.ietf.org/html/rfc8174)] when, and only when, they appear in all capitals, as shown here. -An implementation of this specification is not compliant if it fails to satisfy one or more of the "MUST", "MUST NOT", "REQUIRED", "SHALL", or "SHALL NOT" requirements defined in the specification. Conversely, an implementation of the specification is compliant if it satisfies all the "MUST", "MUST NOT", "REQUIRED", "SHALL", and "SHALL NOT" requirements defined in -the specification. +## FOCUS Feature level + +Under each column defined in the FOCUS specification, there exists a 'Feature level' designation that describes the column as 'Mandatory', 'Conditional', or 'Optional'. Feature level is designated based on the following criteria described in the normative requirements in each column definition: + +* If the existence of a column is described with MUST or MUST NOT, then the feature level is designated as 'Mandatory'. +* If the existence of a column is described as SHOULD or SHOULD NOT, then the feature level is designated as 'Conditional'. +* If the existence of a column is described as MAY or MAY NOT, then the feature level is designated as 'Optional'. ## Conformance Checkers and Validators diff --git a/specification/spec.mdpp b/specification/spec.mdpp index 22024a99b..9d2f532ea 100644 --- a/specification/spec.mdpp +++ b/specification/spec.mdpp @@ -9,7 +9,7 @@ pagetitle: FinOps Open Cost and Usage Specification ## Abstract -FOCUS is an open-source specification for cloud billing data. It defines a common schema for billing data, aligns terminology with the FinOps Framework and defines a minimum set of requirements for billing data. The specification provides clear guideline for billing data generators to produce FinOps-serviceable data. The specification enables FinOps practitioners to perform common FinOps capabilities such as chargeback, cost allocation, budgeting and forecasting etc. using a generic set of instructions, regardless of the origin of the FOCUS compatible dataset. +FOCUS is an open-source specification for billing data. It defines a common schema for billing data, aligns terminology with the FinOps Framework and defines a minimum set of requirements for billing data. The specification provides clear guideline for billing data generators to produce FinOps-serviceable data. The specification enables FinOps practitioners to perform common FinOps capabilities such as chargeback, cost allocation, budgeting and forecasting etc. using a generic set of instructions, regardless of the origin of the FOCUS compatible dataset.
@@ -31,8 +31,14 @@ FOCUS is an open-source specification for cloud billing data. It defines a commo !INCLUDE "attributes/attributes.mdpp",1 +
+ !INCLUDE "use_case_library.md",1 +
+ !INCLUDE "glossary.md",1 +
+ !INCLUDE "appendix/appendix.mdpp",1 From f62e1a6ca3eab84dfbab23413b4ab85d7ed81d70 Mon Sep 17 00:00:00 2001 From: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Date: Fri, 22 Mar 2024 11:52:58 -0700 Subject: [PATCH 17/65] Update tags.md Update tag concept and names --- specification/columns/tags.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/columns/tags.md b/specification/columns/tags.md index 788f59cfe..bd836939c 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -1,6 +1,6 @@ # Tags -The Tags column represents the set of tags assigned to [*tag sources*](#glossary:tag-source) that also account for potential provider-defined or user-defined tag evaluations. Tags are commonly used for scenarios like adding business context to billing data to identify and accurately allocate charges. +The Tags column represents the set of tags assigned to [*tag sources*](#glossary:tag-source) that also account for potential provider-defined or user-defined tag evaluations. In FOCUS, "Tag" is a generic term to describe metadata that can be attached to a resource, account, etc. by a user or provider to help identify it. Tags may also be referred to by providers by other terms, such as labels or networks tags. Tags are commonly used for scenarios like adding business context to billing data to identify and accurately allocate charges. A tag becomes [*finalized*](#glossary:finalized-tag) when a single value is selected from a set of possible tag values assigned to the tag key. When supported by a provider, this can occur when a tag value is set by provider-defined or user-defined rules. @@ -12,7 +12,7 @@ The Tags column adheres to the following requirements: * The Tags column MUST be in [Key-Value Format](#key-valueformat). * A Tag key with a non-null value for a given resource SHOULD be included in the tags column. * A Tag key with a null value for a given resource MAY be included in the tags column depending on the provider's tag finalization process. -* A Tag key that does *not* support a corresponding value, sometimes referred to as a *label*, MUST have a corresponding true (boolean) value set. +* A Tag key that does *not* support a corresponding value, MUST have a corresponding true (boolean) value set. * If Tag finalization is supported, providers MUST publish tag finalization methods and semantics within their respective documentation. * Providers MUST NOT alter user-defined Tag keys or values. From 559b0bb680f8f81ea80988397d43386059378c6b Mon Sep 17 00:00:00 2001 From: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Date: Sat, 23 Mar 2024 10:52:15 -0700 Subject: [PATCH 18/65] Update tags.md Took cnharris10 recommendations. Removed "Tags" description since it is already in glossary. --- specification/columns/tags.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/tags.md b/specification/columns/tags.md index bd836939c..1b7df7112 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -1,6 +1,6 @@ # Tags -The Tags column represents the set of tags assigned to [*tag sources*](#glossary:tag-source) that also account for potential provider-defined or user-defined tag evaluations. In FOCUS, "Tag" is a generic term to describe metadata that can be attached to a resource, account, etc. by a user or provider to help identify it. Tags may also be referred to by providers by other terms, such as labels or networks tags. Tags are commonly used for scenarios like adding business context to billing data to identify and accurately allocate charges. +The Tags column represents the set of tags assigned to [*tag sources*](#glossary:tag-source) that also account for potential provider-defined or user-defined tag evaluations. Tags are commonly used for scenarios like adding business context to billing data to identify and accurately allocate charges. Tags may also be referred to by providers by other terms, such as labels or networks tags. A tag becomes [*finalized*](#glossary:finalized-tag) when a single value is selected from a set of possible tag values assigned to the tag key. When supported by a provider, this can occur when a tag value is set by provider-defined or user-defined rules. From 323046acc76e64e76f52aadb6511810db14f16d6 Mon Sep 17 00:00:00 2001 From: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Date: Mon, 25 Mar 2024 09:27:44 -0700 Subject: [PATCH 19/65] Update specification/columns/tags.md Co-authored-by: Karl <133434112+kk09v@users.noreply.github.com> --- specification/columns/tags.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/tags.md b/specification/columns/tags.md index 1b7df7112..c6e46e9ba 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -1,6 +1,6 @@ # Tags -The Tags column represents the set of tags assigned to [*tag sources*](#glossary:tag-source) that also account for potential provider-defined or user-defined tag evaluations. Tags are commonly used for scenarios like adding business context to billing data to identify and accurately allocate charges. Tags may also be referred to by providers by other terms, such as labels or networks tags. +The Tags column represents the set of tags assigned to [*tag sources*](#glossary:tag-source) that also account for potential provider-defined or user-defined tag evaluations. Tags are commonly used for scenarios like adding business context to billing data to identify and accurately allocate charges. Tags may also be referred to by providers using other terms such as labels. A tag becomes [*finalized*](#glossary:finalized-tag) when a single value is selected from a set of possible tag values assigned to the tag key. When supported by a provider, this can occur when a tag value is set by provider-defined or user-defined rules. From 9ff3ed50536f08544dd45ebbf96927e96814ca69 Mon Sep 17 00:00:00 2001 From: Irena Jurica Date: Fri, 5 Apr 2024 08:21:02 +0200 Subject: [PATCH 20/65] FOCUS #336: Negotiated/Contracted List Unit Price and Cost (#364) - Contracted Unit Price specification and supporting content - Contracted Cost specification and supporting content - glossary update - _Contracted Unit Price included_ --------- Co-authored-by: Michael Flanakin Co-authored-by: Andrew Qu <115758900+aqu-erp@users.noreply.github.com> --- specification/columns/columns.mdpp | 2 + specification/columns/contractedcost.md | 37 +++++++++++ specification/columns/contractedunitprice.md | 32 +++++++++ specification/glossary.md | 8 +++ supporting_content/columns/contractedcost.md | 52 +++++++++++++++ .../columns/contractedunitprice.md | 65 +++++++++++++++++++ 6 files changed, 196 insertions(+) create mode 100644 specification/columns/contractedcost.md create mode 100644 specification/columns/contractedunitprice.md create mode 100644 supporting_content/columns/contractedcost.md create mode 100644 supporting_content/columns/contractedunitprice.md diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index 388ca6739..b51f52a53 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -19,6 +19,8 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "commitmentdiscountid.md",1 !INCLUDE "commitmentdiscountname.md",1 !INCLUDE "commitmentdiscounttype.md",1 +!INCLUDE "contractedcost.md",1 +!INCLUDE "contractedunitprice.md",1 !INCLUDE "effectivecost.md",1 !INCLUDE "invoiceissuer.md",1 !INCLUDE "listcost.md",1 diff --git a/specification/columns/contractedcost.md b/specification/columns/contractedcost.md new file mode 100644 index 000000000..63f98e778 --- /dev/null +++ b/specification/columns/contractedcost.md @@ -0,0 +1,37 @@ +# Contracted Cost + +Contracted Cost represents the cost calculated by multiplying [*contracted unit price*](#glossary:contracted-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). Contracted Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on negotiation activities, by comparing it with [List Cost](#listcost). If negotiated discounts are not applicable, the Contracted Cost defaults to the List Cost. + +The ContractedCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ContractedUnitPrice](#contractedunitprice) is present and not null, multiplying the ContractedUnitPrice by PricingQuantity MUST produce the ContractedCost. + +In cases where the ContractedUnitPrice is present and null, the following applies: + +* The ContractedCost of a charge calculated based on other charges (e.g., when the [ChargeCategory](#chargecategory) is "Tax") MUST be calculated based on the ContractedCost of those related charges. +* The ContractedCost of a charge unrelated to other charges (e.g., when the [ChargeSubcategory](#chargesubcategory) is "Credit") MUST match the [BilledCost](#billedcost). + +## Column ID + +ContractedCost + +## Display Name + +Contracted Cost + +## Description + +Cost calculated by multiplying *contracted unit price* and the corresponding Pricing Quantity. + +## Content Constraints + +| Constraint | Value | +|:----------------|:------------------------| +| Column type | Metric | +| Feature level | Mandatory | +| Allows nulls | False | +| Data type | Decimal | +| Value format | [Numeric Format](#numericformat) | +| Number range | Any valid decimal value | + +## Introduced (version) + +1.0 diff --git a/specification/columns/contractedunitprice.md b/specification/columns/contractedunitprice.md new file mode 100644 index 000000000..bbe2fbebf --- /dev/null +++ b/specification/columns/contractedunitprice.md @@ -0,0 +1,32 @@ +# Contracted Unit Price + +The Contracted Unit Price represents the agreed-upon unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, inclusive of negotiated discounts, if present, while excluding negotiated commitment-based discounts or any other discounts. This price is denominated in the [Billing Currency](#billingcurrency). The Contracted Unit Price is commonly used for calculating savings based on negotiation activities. If negotiated discounts are not applicable, the Contracted Unit Price defaults to the [List Unit Price](#listunitprice). + +The ContractedUnitPrice column SHOULD be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ContractedUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost). + +## Column ID + +ContractedUnitPrice + +## Display Name + +Contracted Unit Price + +## Description + +The agreed-upon unit price for a single Pricing Unit of the associated SKU, inclusive of negotiated discounts, if present, while excluding negotiated commitment-based discounts or any other discounts. + +## Content Constraints + +| Constraint | Value | +|:----------------|:-------------------------------------| +| Column type | Metric | +| Feature level | Conditional | +| Allows nulls | True | +| Data type | Decimal | +| Value format | [Numeric Format](#numericformat) | +| Number range | Any valid non-negative decimal value | + +## Introduced (version) + +1.0 diff --git a/specification/glossary.md b/specification/glossary.md index 36f15dfea..d05208feb 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -76,6 +76,14 @@ A category of compute resources that can be paused or terminated by the CSP with The suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated [SKU](#glossary:sku), exclusive of any discounts. This price is denominated in the [Billing Currency](#glossary:billingcurrency). +Contracted Unit Price + +The agreed-upon unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, inclusive of negotiated discounts, if present, and exclusive of any other discounts. This price is denominated in the [Billing Currency](#glossary:billingcurrency). + +Contracted Unit Price + +The agreed-upon unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, inclusive of negotiated discounts, if present, and exclusive of any other discounts. This price is denominated in the [Billing Currency](#glossary:billingcurrency). + Metric A FOCUS-defined column that provides numeric values, allowing for aggregation operations such as arithmetic operations (sum, multiplication, averaging etc.) and statistical operations. diff --git a/supporting_content/columns/contractedcost.md b/supporting_content/columns/contractedcost.md new file mode 100644 index 000000000..8c23df88a --- /dev/null +++ b/supporting_content/columns/contractedcost.md @@ -0,0 +1,52 @@ +# Column: ContractedCost + +## Example provider mappings + +Current column mappings found in available data sets: + +| Provider | Data set | Column | +|:----------|:------------------------|:-------------------------------------------------------------------------------------------| +| AWS | CUR | Not available | +| GCP | BigQuery Billing Export | Not available? or **cost** (the closest match);
*see Discussion / Scratch space - GCP column mappings for more details* | +| Microsoft | Cost details (actual/amortized) | Not available
Can calculate using UnitPrice * Quantity
*see Discussion / Scratch space - Microsoft column mappings related issues for more details* | +| Microsoft | Cost details (FOCUS `1.0-preview(v1)`) | x_OnDemandCost | +| OCI | Cost and Usage Report | **cost/myCost**
*see Discussion / Scratch space - OCI column mappings for more details* | + +## References and Resources + +### AWS + +* [Data dictionary - AWS Cost and Usage Reports](https://docs.aws.amazon.com/cur/latest/userguide/data-dictionary.html) + +### GCP + +* [Structure of Standard data export | Cloud Billing](https://cloud.google.com/billing/docs/how-to/export-data-bigquery-tables/standard-usage) + +### Microsoft + +* [Understand usage details fields - Microsoft Cost Management](https://learn.microsoft.com/en-us/azure/cost-management-billing/automate/understand-usage-details-fields) + +### OCI + +* [Cost and Usage Reports Overview](https://docs.oracle.com/en-us/iaas/Content/Billing/Concepts/usagereportsoverview.htm) + +## Example usage scenarios + +* *TODO* + +## Discussion / Scratch space + +### GCP column mappings + +* **cost** - The cost of the usage before any credits, to a precision of up to six decimal places. To get the total cost including credits, any credits.amount should be added to cost. + +### Microsoft column mappings related issues + +* TODO + +### OCI column mappings + +* Cost and usage reports contain cost/myCost and cost/myCostOverage columns. + * **cost/myCost** - The cost charged for this line of usage. `myCost` is equal to `usage/billedQuanty * cost/unitPrice`. Note: billedQuantity, myCost, and unitPrice are inclusive of Overage numbers. + * **cost/myCostOverage** - The cost billed for overage usage of a resource. +* Conclusion: Mapping **cost/myCost** to Contracted Cost and cost/myCostOverage to Billed Cost diff --git a/supporting_content/columns/contractedunitprice.md b/supporting_content/columns/contractedunitprice.md new file mode 100644 index 000000000..9be525c3a --- /dev/null +++ b/supporting_content/columns/contractedunitprice.md @@ -0,0 +1,65 @@ +# Column: ContractedUnitPrice + +## Example provider mappings + +Current column mappings found in available data sets: + +| Provider | Data set | Column | +|:----------|:-----------------------------|:-------------------------| +| AWS | CUR | Not available | +| GCP | BigQuery Billing Export;
BigQuery Pricing Data Export;
Cloud Billing API | Not available in BigQuery Billing Export
**price.effective_price** available only in detail export, i.e. available for a subset of resources/services
*see Discussion / Scratch space - GCP column mappings related issues for more details* | +| Microsoft | Cost details (actual/amortized) | UnitPrice
*see Discussion / Scratch space - Microsoft column mappings related issues for more details* | +| Microsoft | Cost details (FOCUS `1.0-preview(v1)`) | x_OnDemandUnitPrice | +| OCI | Cost and Usage Report | **cost/unitPrice** is the best match
*see Discussion / Scratch space - OCI column mappings related issues for more details* | + +## References and Resources + +### AWS + +* [Line item details - AWS Cost and Usage Reports](https://docs.aws.amazon.com/cur/latest/userguide/Lineitem-columns.html) + +### GCP + +* [Structure of Detailed data export | Cloud Billing](https://cloud.google.com/billing/docs/how-to/export-data-bigquery-tables/detailed-usage) +* [Structure of pricing data export | Cloud Billing](https://cloud.google.com/billing/docs/how-to/export-data-bigquery-tables/pricing-data) +* [Get Google Cloud pricing information | Cloud Billing (GCP Cloud Billing API)](https://cloud.google.com/billing/docs/how-to/get-pricing-information-api) + +### Microsoft + +* [Understand usage details fields - Microsoft Cost Management](https://learn.microsoft.com/en-us/azure/cost-management-billing/automate/understand-usage-details-fields) +* [Azure Billing Enterprise APIs - PriceSheet | Microsoft Learn](https://learn.microsoft.com/en-us/rest/api/billing/enterprise/billing-enterprise-api-pricesheet) + * Applies only to EA + * *TODO: Check if there is a Microsoft Custom Prices REST API, which might provide custom prices for all account types* + +### OCI + +* [Cost and Usage Reports Overview](https://docs.oracle.com/en-us/iaas/Content/Billing/Concepts/usagereportsoverview.htm) + +## Example usage scenarios + +* *TODO* + +## Discussion / Scratch space + +### GCP column mappings related issues + +* **price.effective_price** is present only in detail export and thus available only for small subset of services/resources. In order to resolve this information we should rely on **BigQuery Pricing Data Export** and/or **Cloud Billing API**, which provide price related structs (out-of-scope of this document). +* Similar to cost, regardless of the data source we use, the resolved price does not include reductions provided in credits, which aligns with the definition of ContractedUnitPrice. + +### Microsoft column mappings related issues + +* [Azure Billing Enterprise APIs - PriceSheet | Microsoft Learn](https://learn.microsoft.com/en-us/rest/api/billing/enterprise/ provides information for EA. +* TODO: Check if there is a Microsoft Custom Prices REST API, which might provide custom/negotiated prices for all account types. +* **unitPrice** (The price per unit for the charge.) includes commitment based discounts and thus is not applicable for all use cases. Furthermore, + * According to documentation, it is available only for EA and PAYG. + * It is unclear if it's denominated in Billing or Pricing currency. Noticed that for different accounts types different relations apply + * In one case `unitPrice * quantity = costInBillingCurrency` + * In another `unitPrice * quantity = costInUSD` + +### OCI column mappings related issues + +* Cost and usage reports contain **cost/unitPrice** (The cost billed to you for each unit of the resource used.) and **cost/unitPriceOverage** (The cost per unit of usage for overage usage of a resource.) columns. +* Analysis of sample billing data sets revealed the following: + * Encountered records with NULL values in the cost/unitPriceOverage column, even when usage/billedQuantityOverage is not NULL and != 0. This discrepancy is not observed with the cost/unitPrice column. + * Additionally, found records where usage/billedQuantityOverage is NOT NULL and slightly differs from cost/unitPrice. This suggests that the discounted price continues to apply even when the customer exceeds their annual commitment during the commitment/contract period (consistent with OCI documentation). +* Conclusion: we currently **prefer cost/unitPrice** over cost/unitPriceOverage From 0f4db4296d9f7164b5291f45833b3f69f2620aab Mon Sep 17 00:00:00 2001 From: Alex Hullah Date: Tue, 9 Apr 2024 16:01:56 +0100 Subject: [PATCH 21/65] 330 charge category credit refund (#355) Updated to breakout refunds and credits from charge category. to be handled in a new adjustment category column. This will allow all main charge categories (Usage, Purchase, Tax) to easily classify regular usage, from usage specific refunds or general purpose incentives / credits --------- Co-authored-by: Shawn Alpay <77511110+salpaysenturus@users.noreply.github.com> Co-authored-by: Udam Dewaraja Co-authored-by: Christopher Harris Co-authored-by: Andrew Qu <115758900+aqu-erp@users.noreply.github.com> Co-authored-by: Michael Flanakin --- specification/columns/chargecategory.md | 11 +-- specification/columns/chargeclass.md | 38 +++++++++ specification/columns/columns.mdpp | 1 + specification/columns/skupriceid.md | 2 +- .../{chargetype.md => chargecategory.md} | 83 +++++++++++++++++++ 5 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 specification/columns/chargeclass.md rename supporting_content/columns/{chargetype.md => chargecategory.md} (68%) diff --git a/specification/columns/chargecategory.md b/specification/columns/chargecategory.md index f010bb830..bb51ffbe5 100644 --- a/specification/columns/chargecategory.md +++ b/specification/columns/chargecategory.md @@ -1,6 +1,6 @@ # Charge Category -A Charge Category indicates whether the row represents an upfront or recurring fee, cost of usage that already occurred, an after-the-fact [*adjustment*](#glossary:adjustment) (e.g., credits), or taxes. The Charge Category is commonly used to identify prepaid purchases separately from usage-based charges, to separate taxes that may require special handling, or to apply finer-grained allocation logic to purchases or *adjustments*. +A Charge Category is the highest level classification for the type of charge that the billing row represents. The Charge Category is commonly used to identify prepaid purchases separately from usage-based charges or to separate charges that may require special handling from regular usage. The ChargeCategory column MUST be present in the billing data and MUST NOT be null. This column is of type String and MUST be one of the allowed values. @@ -30,10 +30,11 @@ Allowed values: | Value | Description | | :--------- | :------------------------------------| -| Adjustment | Any adjustments that are applied after the original usage or purchase row. Adjustments may be related to multiple charges. | -| Purchase | Charges for the acquisition of a service or resource bought upfront or on a recurring basis. | -| Tax | Applicable taxes that are levied by the relevant authorities. Tax charges may vary depending on factors such as the location, jurisdiction, and local or federal regulations. | -| Usage | Charges based on the quantity of a service or resource that was consumed over a given period of time. | +| Usage | Positive or negative charges based on the quantity of a service or resource that was consumed over a given period of time including refunds. | +| Purchase | Positive or negative charges for the acquisition of a service or resource bought upfront or on a recurring basis inluding refunds. | +| Tax | Positive or negative applicable taxes that are levied by the relevant authorities including refunds. Tax charges may vary depending on factors such as the location, jurisdiction, and local or federal regulations. | +| Credit | Positive or negative charges granted by the provider for various scenarios e.g promotional credits or corrections to promotional credits. | +| Adjustment | Positive or negative charges the provider applies that do not fall into other category values. | ## Introduced (version) diff --git a/specification/columns/chargeclass.md b/specification/columns/chargeclass.md new file mode 100644 index 000000000..fbe619814 --- /dev/null +++ b/specification/columns/chargeclass.md @@ -0,0 +1,38 @@ +# Charge Class + +A Charge Class indicates whether the row represents a regular charge or a correction to one or more previous charges. Charge Class is commonly used to differentiate refunds from regularly incurred charges. + +The ChargeClass column MUST be present and MUST NOT be null. This column is of type String and MUST be one of the allowed values. + +## Column ID + +ChargeClass + +## Display Name + +Charge Class + +## Description + +Indicates whether the row represents a regular charge or a correction to one or more previous charges, its primary use iis for differentiating refunds from normal usage. + +## Content Constraints + +| Constraint | Value | +| :-------------- | :------------- | +| Column type | Dimension | +| Column required | True | +| Allows nulls | False | +| Data type | String | +| Value format | Allowed values | + +Allowed values: + +| Value | Description | +| :--------- | :------------------------------------| +| Regular | Standard charges for services used or purchased. | +| Correction | Modification to one or more previous charges, like refunds and credit modifications. | + +## Introduced (version) + +0.5 diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index b51f52a53..57af24748 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -10,6 +10,7 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "billingperiodend.md",1 !INCLUDE "billingperiodstart.md",1 !INCLUDE "chargecategory.md",1 +!INCLUDE "chargeclass.md",1 !INCLUDE "chargedescription.md",1 !INCLUDE "chargefrequency.md",1 !INCLUDE "chargeperiodend.md",1 diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index a1830260f..be502458c 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -2,7 +2,7 @@ A SKU Price ID is a unique identifier that defines the unit price used to calculate the charge. SKU Price ID can be referenced on a [*price list*](#glossary:price-list) published by a provider to look up detailed information, including a corresponding list unit price. The composition of the properties associated with the SKU Price ID may differ across providers. SKU Price ID is commonly used for analyzing cost based on pricing properties such as Terms and Tiers. -The SkuPriceId column SHOULD be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider-published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage". SkuPriceId MUST NOT be null when [ChargeSubcategory](#chargesubcategory) is "Refund" and the refund is related to charges with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. +The SkuPriceId column MUST be present in the billing data. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage" and [ChargeClass](#chargeclass) is "Regular". The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Credit" or "Adjustment" and the charge is associated with a specific SkuPriceId. SkuPriceId MUST NOT be null when [ChargeClass](#chargeclass) is "Correction" and the correction is associated with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. ## Column ID diff --git a/supporting_content/columns/chargetype.md b/supporting_content/columns/chargecategory.md similarity index 68% rename from supporting_content/columns/chargetype.md rename to supporting_content/columns/chargecategory.md index d0ba5616f..073eada22 100644 --- a/supporting_content/columns/chargetype.md +++ b/supporting_content/columns/chargecategory.md @@ -37,6 +37,84 @@ Current values observed in billing data for various scenarios: | Microsoft | Adjustment | Adjustment | Rounding errors. | | Microsoft | Tax | Tax | US sales tax or VAT. | +Current scenarios considered include: + +### Option 1 + +| Value | Description | +| :--------- | :------------------------------------| +| Refund | Any adjustments that are applied after the original usage or purchase row. Adjustments may be related to multiple charges. (NOTE: Tax excluded) | +| Credit | Credits assoicated with promotional usage or incentives | +| Purchase | Charges for the acquisition of a service or resource bought upfront or on a recurring basis. | +| Tax | Applicable taxes that are levied by the relevant authorities. Tax charges may vary depending on factors such as the location, jurisdiction, and local or federal regulations. | +| Usage | Charges based on the quantity of a service or resource that was consumed over a given period of time. | + +ISSUE: Tax cannot be classified correctly, assuming refunds and purchases have a tax implication then we would need to look for negative tax values matching the refund line in order ot acertain the total value of the refund. + +### Option 2: + +| Value | Description | +| :--------- | :------------------------------------| +| Purchase | Charges for the acquisition of a service or resource bought upfront or on a recurring basis. | +| Tax | Applicable taxes that are levied by the relevant authorities. Tax charges may vary depending on factors such as the location, jurisdiction, and local or federal regulations. | +| Usage | Charges based on the quantity of a service or resource that was consumed over a given period of time. | + + +New Column: Adjustment Category + +| Value | Description | +| :--------- | :------------------------------------| +| NULL | Default value for all incomming charges. | +| Refund | Refunded related to usage or purchase specific activities (expects a matching 'tax' transaction) | +| Credit | Promotional / negotiated / incentive credits provided at providers discression (does NOT expect a matching 'tax' transaction) | + +Permutations: + +| Charge Category | Adjustment Category | Example usage | +| :--------- | :------------------------------------|:------------------------------| +|Usage | NULL | general usage | +|Usage | Refund | service specific refunds /..e.g miss billing | +|Usage | Credit | service specific incentives | +|Purchase | NULL | general marketplace or 3rd party purchase | +|Purchase | Refund | bulk / general refunds | +|Purchase | Credit | Non-service / usage specific credits | +|Tax | NULL | general tax | +|Tax | Refund | tax refund for usage or purchase refunded | +|Tax | Credit | NOT APPLICABLE | + +### Option 3: + +| Value | Description | +| :--------- | :------------------------------------| +| Credit | Credits assoicated with promotional usage or incentives | +| Purchase | Charges for the acquisition of a service or resource bought upfront or on a recurring basis. | +| Tax | Applicable taxes that are levied by the relevant authorities. Tax charges may vary depending on factors such as the location, jurisdiction, and local or federal regulations. | +| Usage | Charges based on the quantity of a service or resource that was consumed over a given period of time. | + +New Column: Adjustment Category + +| Value | Description | +| :--------- | :------------------------------------| +| NULL | Default value for all incomming charges. | +| Refund | Refunded related to usage or purchase specific activities (expects a matching 'tax' transaction) | +| Bulk Refund | General refund (expects a matching 'tax' transaction) | +| Rounding Error | Small corrections - Applicable to current billing period only | +| Other | Catch all | + +Permutations: + +| Charge Category | Adjustment Category | Example usage | +| :--------- | :------------------------------------|:------------------------------| +|Usage | NULL | general usage | +|Usage | Refund | service specific refunds /..e.g miss billing | +|Purchase | NULL | general marketplace or 3rd party purchase | +|Purchase | Refund | specific / 3rd party refund | +|Tax | NULL | general tax | +|Tax | Refund | tax refund for usage or purchase refunded | +|Credit | NULL | service specific incentives | +|Credit | Other | vendor specific / non usage related incentives | + + ## Discussion / Scratch space - What are the different types of spend that we want to group? @@ -55,6 +133,11 @@ Current values observed in billing data for various scenarios: - Is it Recurring or not? (Attribute about the Purchase?) - What Charge Category values can BE recurring? - What Charge Category values for "Free Tier" with usage limits and "Free Trial" offers? +- What adjustment categories do we need to group? +- Do we need to normalize adjustment categories? +- Refunds - $s coming back after the original charge +- Credits are typically based on agreements for migration of workloads, or promotional items negotiated with the provider +- Balance transfers - how do you show what a balance transfer is if in the unliely event you close an account with a positive value and open a new account ### Example mappings for normalized values From 6d30a2ee029519c3edf0c167e35afa9126147a97 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Fri, 12 Apr 2024 04:47:03 +1000 Subject: [PATCH 22/65] Moved license details into unique file and updated to match project procedures (#378) Moved license details into unique file and updated to match project procedures #377 Signed-off-by: Mike Fuller --- LICENSE.txt | 2 +- license.md | 32 +++++++++++++++++++++ specification/license.md | 1 + specification/spec.mdpp | 2 ++ specification/versions/candidate_release.md | 7 ----- specification/versions/main.md | 8 ------ specification/versions/working_draft.md | 7 ----- 7 files changed, 36 insertions(+), 23 deletions(-) create mode 100644 license.md create mode 120000 specification/license.md diff --git a/LICENSE.txt b/LICENSE.txt index 6f93e4305..232e61ba7 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1 +1 @@ -TBC \ No newline at end of file +See: License.md \ No newline at end of file diff --git a/license.md b/license.md new file mode 100644 index 000000000..fcfb59446 --- /dev/null +++ b/license.md @@ -0,0 +1,32 @@ +## Document Use License + +Copyright (c) Joint Development Foundation Projects, LLC, FinOps Open Cost and Usage Specification (FOCUS) Series and its contributors. The materials in this repository are made available under the Creative Commons Attribution 4.0 International license (CC-BY-4.0), available at [https://creativecommons.org/licenses/by/4.0/legalcode](https://creativecommons.org/licenses/by/4.0/legalcode). + +Shield: [![CC BY 4.0][cc-by-shield]][cc-by] + +This work is made available under: +[Creative Commons Attribution 4.0 International License][cc-by]. + +[![CC BY 4.0][cc-by-image]][cc-by] + +[cc-by]: http://creativecommons.org/licenses/by/4.0/ +[cc-by-image]: https://i.creativecommons.org/l/by/4.0/88x31.png +[cc-by-shield]: https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg + +THESE MATERIALS ARE PROVIDED "AS IS." The parties expressly disclaim +any warranties (express, implied, or otherwise), including implied +warranties of merchantability, non-infringement, fitness for a particular +purpose, or title, related to the materials. The entire risk as to +implementing or otherwise using the materials is assumed by the +implementer and user. IN NO EVENT WILL THE PARTIES BE LIABLE TO ANY +OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF +ANY KIND WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, +WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR +OTHERWISE, AND WHETHER OR NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +This document is governed by the Patent Policy Option 3: Open Web Foundation 1.0 Mode: +See [project charter](https://github.com/FinOps-Open-Cost-and-Usage-Spec/foundation/blob/main/FOCUS_-_Membership_Agreement_Package_for_use.pdf). + +
diff --git a/specification/license.md b/specification/license.md new file mode 120000 index 000000000..936e42433 --- /dev/null +++ b/specification/license.md @@ -0,0 +1 @@ +../license.md \ No newline at end of file diff --git a/specification/spec.mdpp b/specification/spec.mdpp index 9d2f532ea..f8f659f72 100644 --- a/specification/spec.mdpp +++ b/specification/spec.mdpp @@ -7,6 +7,8 @@ pagetitle: FinOps Open Cost and Usage Specification !INCLUDE "version.md",0 +!INCLUDE "license.md",0 + ## Abstract FOCUS is an open-source specification for billing data. It defines a common schema for billing data, aligns terminology with the FinOps Framework and defines a minimum set of requirements for billing data. The specification provides clear guideline for billing data generators to produce FinOps-serviceable data. The specification enables FinOps practitioners to perform common FinOps capabilities such as chargeback, cost allocation, budgeting and forecasting etc. using a generic set of instructions, regardless of the origin of the FOCUS compatible dataset. diff --git a/specification/versions/candidate_release.md b/specification/versions/candidate_release.md index 069e1b950..4da911b32 100644 --- a/specification/versions/candidate_release.md +++ b/specification/versions/candidate_release.md @@ -22,11 +22,4 @@ This document should be considered a draft document and may be updated, replaced This document was produced by a group operating under the Joint Development Foundation Projects agreement. FOCUS maintains a public list of any patent disclosures made in connection with the deliverables of the group; [that page](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/blob/working_draft/ipr.md) also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information. -This document is governed by the Patent Policy Option 3: Open Web Foundation 1.0 Mode: -See [project charter](https://github.com/FinOps-Open-Cost-and-Usage-Spec/foundation/blob/main/FOCUS_-_Membership_Agreement_Package_for_use.pdf). -
- -## Document Use License - -

FinOps Open Cost and Usage Specification is licensed under CC BY 4.0

diff --git a/specification/versions/main.md b/specification/versions/main.md index cdf47c6a6..769131edf 100644 --- a/specification/versions/main.md +++ b/specification/versions/main.md @@ -12,12 +12,4 @@ This is a published release of the FinOps Open Cost and Usage Specification. This document was produced by a group operating under the Joint Development Foundation Projects agreement. FOCUS maintains a public list of any patent disclosures made in connection with the deliverables of the group; [that page](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/blob/working_draft/ipr.md) also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information. -This document is governed by the Patent Policy Option 3: Open Web Foundation 1.0 Mode: -See [project charter](https://github.com/FinOps-Open-Cost-and-Usage-Spec/foundation/blob/main/FOCUS_-_Membership_Agreement_Package_for_use.pdf). -
- -## Document Use License - -

FinOps Open Cost and Usage Specification is licensed under CC BY 4.0

- diff --git a/specification/versions/working_draft.md b/specification/versions/working_draft.md index 764d9e72d..e9c175a71 100644 --- a/specification/versions/working_draft.md +++ b/specification/versions/working_draft.md @@ -22,11 +22,4 @@ This document should be considered a draft document and may be updated, replaced This document was produced by a group operating under the Joint Development Foundation Projects agreement. FOCUS maintains a public list of any patent disclosures made in connection with the deliverables of the group; [that page](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/blob/working_draft/ipr.md) also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information. -This document is governed by the Patent Policy Option 3: Open Web Foundation 1.0 Mode: -See [project charter](https://github.com/FinOps-Open-Cost-and-Usage-Spec/foundation/blob/main/FOCUS_-_Membership_Agreement_Package_for_use.pdf). -
- -## Document Use License - -

FinOps Open Cost and Usage Specification is licensed under CC BY 4.0

From 650a84678f998a9bee198cc310d647b7e44002a0 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Fri, 12 Apr 2024 05:05:08 +1000 Subject: [PATCH 23/65] Add new tier to Feature Level #392 (#393) As per Issue 392. In order to clearly determine the difference between SHOULD/RECOMMENDED columns with no conditions from those which are MUST w/conditions Adding a new level 'Recommended' Signed-off-by: Mike Fuller --- specification/overview.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specification/overview.md b/specification/overview.md index c98a3e35d..1a0cc3f45 100644 --- a/specification/overview.md +++ b/specification/overview.md @@ -81,9 +81,10 @@ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SH Under each column defined in the FOCUS specification, there exists a 'Feature level' designation that describes the column as 'Mandatory', 'Conditional', or 'Optional'. Feature level is designated based on the following criteria described in the normative requirements in each column definition: -* If the existence of a column is described with MUST or MUST NOT, then the feature level is designated as 'Mandatory'. -* If the existence of a column is described as SHOULD or SHOULD NOT, then the feature level is designated as 'Conditional'. -* If the existence of a column is described as MAY or MAY NOT, then the feature level is designated as 'Optional'. +* If the existence of a column is described with MUST with no conditions of when it applies, then the feature level is designated as 'Mandatory'. +* If the existence of a column is described as MUST with conditions of when it applies, then the feature level is designated as 'Conditional'. +* If the existence of a column is described as RECOMMENDED, then the feature level is designated as 'Recommended'. +* If the existence of a column is described as MAY, then the feature level is designated as 'Optional'. ## Conformance Checkers and Validators From e78c85c4577b2f49f56fe57d165716e166b81339 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 10 Apr 2024 10:52:01 -0700 Subject: [PATCH 24/65] update availabilityzone based on issue 387 --- specification/columns/availabilityzone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/availabilityzone.md b/specification/columns/availabilityzone.md index 503e50aae..3c48fb0a8 100644 --- a/specification/columns/availabilityzone.md +++ b/specification/columns/availabilityzone.md @@ -2,7 +2,7 @@ An [*availability zone*](#glossary:availability-zone) is a provider-assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. Availability Zone is commonly used for scenarios like analyzing cross-zone data transfer usage and the corresponding cost based on where [*resources*](#glossary:resource) are deployed. -The AvailabilityZone column SHOULD be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. +The AvailabilityZone column SHOULD be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. The AvailabilityZone column MAY NOT be present in the billing dataset when the provider does not support provisioning resources into an Availability Zone. However, if it is provided, it MUST be null. ## Column ID From 7ef13c8c09a37ab599d3159ae50e9be51f3ecf97 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 10 Apr 2024 18:41:44 -0700 Subject: [PATCH 25/65] Update specification/columns/availabilityzone.md The TF-2 agreed to replace SHOULD for RECOMMENDED --- specification/columns/availabilityzone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/availabilityzone.md b/specification/columns/availabilityzone.md index 3c48fb0a8..cec77817c 100644 --- a/specification/columns/availabilityzone.md +++ b/specification/columns/availabilityzone.md @@ -2,7 +2,7 @@ An [*availability zone*](#glossary:availability-zone) is a provider-assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. Availability Zone is commonly used for scenarios like analyzing cross-zone data transfer usage and the corresponding cost based on where [*resources*](#glossary:resource) are deployed. -The AvailabilityZone column SHOULD be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. The AvailabilityZone column MAY NOT be present in the billing dataset when the provider does not support provisioning resources into an Availability Zone. However, if it is provided, it MUST be null. +The AvailabilityZone column is RECOMMENDED to be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. ## Column ID From b638e2d8e4a3873b52715d3e187f05401c0f2763 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 10 Apr 2024 18:42:52 -0700 Subject: [PATCH 26/65] Update availabilityzone.md Change from Conditional to recommended. --- specification/columns/availabilityzone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/availabilityzone.md b/specification/columns/availabilityzone.md index cec77817c..d998b5544 100644 --- a/specification/columns/availabilityzone.md +++ b/specification/columns/availabilityzone.md @@ -21,7 +21,7 @@ A provider-assigned identifier for a physically separated and isolated area with | Constraint | Value | |:----------------|:-----------------| | Column type | Dimension | -| Feature level | Conditional | +| Feature level | Recommended | | Allows nulls | True | | Data type | String | | Value format | \ | From 3b859ecb2f9797b13b67ef4f804f0eae24a0b22e Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 10 Apr 2024 19:16:03 -0700 Subject: [PATCH 27/65] change must for recommended and set feature level to recommended --- specification/columns/chargefrequency.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/columns/chargefrequency.md b/specification/columns/chargefrequency.md index d0e3b623c..69c414387 100644 --- a/specification/columns/chargefrequency.md +++ b/specification/columns/chargefrequency.md @@ -2,7 +2,7 @@ Charge Frequency indicates how often a charge will occur. Along with the [charge period](#glossary:chargeperiod) related columns, the Charge Frequency is commonly used to understand recurrence periods (e.g., monthly, yearly), forecast upcoming charges, and differentiate between one-time and recurring fees for purchases. -The ChargeFrequency column MUST be present in the billing data and MUST NOT be null. This column is of type String and MUST be one of the allowed values. When [ChargeCategory](#chargecategory) is "Purchase", ChargeFrequency MUST NOT be "Usage-Based". +The ChargeFrequency column is RECOMMENDED be present in the billing data and MUST NOT be null. This column is of type String and MUST be one of the allowed values. When [ChargeCategory](#chargecategory) is "Purchase", ChargeFrequency MUST NOT be "Usage-Based". ## Column ID @@ -21,7 +21,7 @@ Indicates how often a charge will occur. | Constraint | Value | |:----------------|:---------------| | Column type | Dimension | -| Feature level | Mandatory | +| Feature level | Recommended | | Allows nulls | False | | Data type | String | | Value format | Allowed values | From ca9211bb9741ddec3a0d2a89e27a4f29d89ddc2c Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Fri, 12 Apr 2024 07:58:02 -0700 Subject: [PATCH 28/65] Fix introduced version references to be accurate (#384) While we still need to decide whether to reference pre-release versions in the spec, the current spec already does and many of them are wrong. This PR fixes those that are wrong to at least be accurate. I figure we can have a separate conversation about excluding pre-release versions and update everything based on that. This PR only fixes what's currently wrong in the spec today and isn't making a statement about whether or not pre-release versions should be in the spec. --- specification/attributes/discount_handling.md | 2 +- specification/attributes/key_value_format.md | 2 +- specification/attributes/numeric_format.md | 2 +- specification/attributes/unit_format.md | 2 +- specification/columns/chargedescription.md | 2 +- specification/columns/chargefrequency.md | 2 +- specification/columns/chargesubcategory.md | 2 +- specification/columns/commitmentdiscountcategory.md | 2 +- specification/columns/commitmentdiscountid.md | 2 +- specification/columns/commitmentdiscountname.md | 2 +- specification/columns/commitmentdiscounttype.md | 2 +- specification/columns/listcost.md | 2 +- specification/columns/listunitprice.md | 2 +- specification/columns/pricingcategory.md | 2 +- specification/columns/pricingquantity.md | 2 +- specification/columns/pricingunit.md | 2 +- specification/columns/regionid.md | 2 +- specification/columns/regionname.md | 2 +- specification/columns/resourcetype.md | 2 +- specification/columns/skuid.md | 2 +- specification/columns/skupriceid.md | 2 +- specification/columns/tags.md | 2 +- specification/columns/usagequantity.md | 2 +- specification/columns/usageunit.md | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/specification/attributes/discount_handling.md b/specification/attributes/discount_handling.md index 06e31ebd9..df3c99ab7 100644 --- a/specification/attributes/discount_handling.md +++ b/specification/attributes/discount_handling.md @@ -46,4 +46,4 @@ None ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/attributes/key_value_format.md b/specification/attributes/key_value_format.md index 478090606..42beb4b00 100644 --- a/specification/attributes/key_value_format.md +++ b/specification/attributes/key_value_format.md @@ -29,4 +29,4 @@ None ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/attributes/numeric_format.md b/specification/attributes/numeric_format.md index 065690c64..9f84daacc 100644 --- a/specification/attributes/numeric_format.md +++ b/specification/attributes/numeric_format.md @@ -75,4 +75,4 @@ None ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/attributes/unit_format.md b/specification/attributes/unit_format.md index 646b55166..ab88e5994 100644 --- a/specification/attributes/unit_format.md +++ b/specification/attributes/unit_format.md @@ -92,4 +92,4 @@ None ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/chargedescription.md b/specification/columns/chargedescription.md index 2cbdbe6f7..dd6f5b58f 100644 --- a/specification/columns/chargedescription.md +++ b/specification/columns/chargedescription.md @@ -28,4 +28,4 @@ Self-contained summary of the charge's purpose and price. ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/chargefrequency.md b/specification/columns/chargefrequency.md index 69c414387..3fa5319c1 100644 --- a/specification/columns/chargefrequency.md +++ b/specification/columns/chargefrequency.md @@ -36,4 +36,4 @@ Allowed values: ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/chargesubcategory.md b/specification/columns/chargesubcategory.md index d8a58866a..1d3e83826 100644 --- a/specification/columns/chargesubcategory.md +++ b/specification/columns/chargesubcategory.md @@ -61,4 +61,4 @@ Allowed values when ChargeCategory is "Adjustment": ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/commitmentdiscountcategory.md b/specification/columns/commitmentdiscountcategory.md index 081887a39..9243b55dc 100644 --- a/specification/columns/commitmentdiscountcategory.md +++ b/specification/columns/commitmentdiscountcategory.md @@ -35,4 +35,4 @@ Allowed values: ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/commitmentdiscountid.md b/specification/columns/commitmentdiscountid.md index f61736b93..49dc7007e 100644 --- a/specification/columns/commitmentdiscountid.md +++ b/specification/columns/commitmentdiscountid.md @@ -28,4 +28,4 @@ The identifier assigned to a *commitment-based discount* by the provider. ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/commitmentdiscountname.md b/specification/columns/commitmentdiscountname.md index 282fd8970..b4f116470 100644 --- a/specification/columns/commitmentdiscountname.md +++ b/specification/columns/commitmentdiscountname.md @@ -28,4 +28,4 @@ The display name assigned to a *commitment-based discount*. ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/commitmentdiscounttype.md b/specification/columns/commitmentdiscounttype.md index d1417546f..156aa77be 100644 --- a/specification/columns/commitmentdiscounttype.md +++ b/specification/columns/commitmentdiscounttype.md @@ -28,4 +28,4 @@ A provider-assigned identifier for the type of *commitment-based discount* appli ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/listcost.md b/specification/columns/listcost.md index 3cbbd7d4d..f4c0765b0 100644 --- a/specification/columns/listcost.md +++ b/specification/columns/listcost.md @@ -34,4 +34,4 @@ Cost calculated by multiplying List Unit Price and the corresponding Pricing Qua ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/listunitprice.md b/specification/columns/listunitprice.md index 5de53abad..3a1f79d4c 100644 --- a/specification/columns/listunitprice.md +++ b/specification/columns/listunitprice.md @@ -29,4 +29,4 @@ The suggested provider-published unit price for a single Pricing Unit of the ass ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/pricingcategory.md b/specification/columns/pricingcategory.md index 9cc5701ba..65c42fd8f 100644 --- a/specification/columns/pricingcategory.md +++ b/specification/columns/pricingcategory.md @@ -45,4 +45,4 @@ Allowed values: ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/pricingquantity.md b/specification/columns/pricingquantity.md index 19d2e8e92..8f8d6fd67 100644 --- a/specification/columns/pricingquantity.md +++ b/specification/columns/pricingquantity.md @@ -29,4 +29,4 @@ The volume of a given SKU associated with a *resource* or *service* used or purc ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/pricingunit.md b/specification/columns/pricingunit.md index 67f89aae3..dbd3d992b 100644 --- a/specification/columns/pricingunit.md +++ b/specification/columns/pricingunit.md @@ -33,4 +33,4 @@ Provider-specified measurement unit for determining unit prices, indicating how ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/regionid.md b/specification/columns/regionid.md index f751b71e6..85174257d 100644 --- a/specification/columns/regionid.md +++ b/specification/columns/regionid.md @@ -28,4 +28,4 @@ Provider-assigned identifier for an isolated geographic area where a *resource* ## Introduced (version) -0.5 +1.0 diff --git a/specification/columns/regionname.md b/specification/columns/regionname.md index 03f389f0d..588c5b8f3 100644 --- a/specification/columns/regionname.md +++ b/specification/columns/regionname.md @@ -28,4 +28,4 @@ The name of an isolated geographic area where a *resource* is provisioned or a * ## Introduced (version) -0.5 +1.0 diff --git a/specification/columns/resourcetype.md b/specification/columns/resourcetype.md index 2931ca3ef..54e7eabae 100644 --- a/specification/columns/resourcetype.md +++ b/specification/columns/resourcetype.md @@ -28,4 +28,4 @@ The kind of *resource* the charge applies to. ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/skuid.md b/specification/columns/skuid.md index f8988d685..80f490ecc 100644 --- a/specification/columns/skuid.md +++ b/specification/columns/skuid.md @@ -28,4 +28,4 @@ A unique identifier that defines a provider-supported construct for organizing p ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index be502458c..42577a331 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -28,4 +28,4 @@ A unique identifier that defines the unit price used to calculate the charge. ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/tags.md b/specification/columns/tags.md index c6e46e9ba..c34b5b63f 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -79,4 +79,4 @@ The set of tags assigned to *tag sources* that account for potential provider-de ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md index 7ab85ea9e..0cd552757 100644 --- a/specification/columns/usagequantity.md +++ b/specification/columns/usagequantity.md @@ -29,4 +29,4 @@ The volume of a given SKU associated with a *resource* or *service* used or purc ## Introduced (version) -1.0 +1.0-preview diff --git a/specification/columns/usageunit.md b/specification/columns/usageunit.md index 171cd2f69..7abc49170 100644 --- a/specification/columns/usageunit.md +++ b/specification/columns/usageunit.md @@ -28,4 +28,4 @@ Provider-specified measurement unit indicating how a provider measures usage or ## Introduced (version) -1.0 +1.0-preview From 1ade5c711b188affeaa29623af458d18369c8089 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 10 Apr 2024 19:33:25 -0700 Subject: [PATCH 29/65] set the column with must plus condition --- specification/columns/commitmentdiscountcategory.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/specification/columns/commitmentdiscountcategory.md b/specification/columns/commitmentdiscountcategory.md index 9243b55dc..8f89c748b 100644 --- a/specification/columns/commitmentdiscountcategory.md +++ b/specification/columns/commitmentdiscountcategory.md @@ -2,7 +2,13 @@ Commitment Discount Category indicates whether the [*commitment-based discount*](#glossary:commitment-based-discount) identified in the CommitmentDiscountId column is based on usage quantity or cost (aka "spend"). -The CommitmentDiscountCategory column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. The CommitmentDiscountCategory MUST be one of the allowed values. +The CommitmentDiscountCategory column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String data and MUST contain one of the allowed enumerated values: +* "Spend": Commitment-based discounts that require a predetermined amount of spend. +* "Usage": Commitment-based discounts that require a predetermined amount of usage. + +Additionally: + IF [CommitmentDiscountId](#commitmentdiscountid) is null, THEN CommitmentDiscountCategory MUST also be null. + IF [CommitmentDiscountId](#commitmentdiscountid) is not null, THEN CommitmentDiscountCategory MUST NOT be null and adhere to the allowed enumerated values. ## Column ID From 6dfdc92d3583a6ec9c248091e4fa719fd1b30287 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Wed, 10 Apr 2024 21:56:13 -0700 Subject: [PATCH 30/65] change should to must with a conditional --- specification/columns/chargesubcategory.md | 2 +- specification/columns/commitmentdiscountid.md | 2 +- specification/columns/commitmentdiscountname.md | 2 +- specification/columns/commitmentdiscounttype.md | 2 +- specification/columns/contractedunitprice.md | 2 +- specification/columns/listunitprice.md | 2 +- specification/columns/pricingcategory.md | 2 +- specification/columns/regionid.md | 2 +- specification/columns/regionname.md | 2 +- specification/columns/resourceid.md | 2 +- specification/columns/resourcename.md | 2 +- specification/columns/resourcetype.md | 2 +- specification/columns/skuid.md | 2 +- specification/columns/skupriceid.md | 2 +- specification/columns/subaccountid.md | 2 +- specification/columns/subaccountname.md | 2 +- specification/columns/tags.md | 2 +- specification/columns/usagequantity.md | 2 +- specification/columns/usageunit.md | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/specification/columns/chargesubcategory.md b/specification/columns/chargesubcategory.md index 1d3e83826..207fd884f 100644 --- a/specification/columns/chargesubcategory.md +++ b/specification/columns/chargesubcategory.md @@ -10,7 +10,7 @@ When Charge Category is "Adjustment", the Charge Subcategory indicates what kind ChargeSubcategory MUST follow the requirements listed below: -* The ChargeSubcategory column SHOULD be present in the billing data when the provider supports sub-categorization of the [Charge Category](#chargecategory) values. +* The ChargeSubcategory column MUST be present in the billing data when the provider supports sub-categorization of the [Charge Category](#chargecategory) values. * ChargeSubcategory is of type String and MUST be one of the allowed values. * ChargeSubcategory MUST NOT be null when ChargeCategory is "Usage" and the charge is covered by a *commitment*. * When a usage charge is covered by a *commitment*, ChargeSubcategory MUST be "Used Commitment". diff --git a/specification/columns/commitmentdiscountid.md b/specification/columns/commitmentdiscountid.md index 49dc7007e..1824d5407 100644 --- a/specification/columns/commitmentdiscountid.md +++ b/specification/columns/commitmentdiscountid.md @@ -2,7 +2,7 @@ A Commitment Discount ID is the identifier assigned to a [*commitment-based discount*](#glossary:commitment-based-discount) by the provider. Commitment Discount ID is commonly used for scenarios like chargeback for *commitments* and savings per *commitment-based discount*. -The CommitmentDiscountId column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String and MUST NOT contain null values when a charge is related to a *commitment-based discount*. When a charge is not associated with a *commitment-based discount*, the column MUST be null. CommitmentDiscountId MUST be unique within the provider. +The CommitmentDiscountId column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String and MUST NOT contain null values when a charge is related to a *commitment-based discount*. When a charge is not associated with a *commitment-based discount*, the column MUST be null. CommitmentDiscountId MUST be unique within the provider. ## Column ID diff --git a/specification/columns/commitmentdiscountname.md b/specification/columns/commitmentdiscountname.md index b4f116470..2b384b480 100644 --- a/specification/columns/commitmentdiscountname.md +++ b/specification/columns/commitmentdiscountname.md @@ -2,7 +2,7 @@ A Commitment Discount Name is the display name assigned to a [*commitment-based discount*](#glossary:commitment-based-discount). -The CommitmentDiscountName column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String. The CommitmentDiscountName value MUST be null if the charge is not related to a *commitment-based discount* and MAY be null if a display name cannot be assigned to a *commitment-based discount*. CommitmentDiscountName MUST NOT be null if a display name can be assigned to a *commitment-based discount*. +The CommitmentDiscountName column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String. The CommitmentDiscountName value MUST be null if the charge is not related to a *commitment-based discount* and MAY be null if a display name cannot be assigned to a *commitment-based discount*. CommitmentDiscountName MUST NOT be null if a display name can be assigned to a *commitment-based discount*. ## Column ID diff --git a/specification/columns/commitmentdiscounttype.md b/specification/columns/commitmentdiscounttype.md index 156aa77be..3248d7b89 100644 --- a/specification/columns/commitmentdiscounttype.md +++ b/specification/columns/commitmentdiscounttype.md @@ -2,7 +2,7 @@ Commitment Discount Type is a provider-assigned name to identify the type of [*commitment-based discount*](#glossary:commitment-based-discount) applied to the [*row*](#glossary:row). -The CommitmentDiscountType column SHOULD be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. Providers MUST use a consistent value format and a set of values for CommitmentDiscountType within their billing datasets. +The CommitmentDiscountType column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. Providers MUST use a consistent value format and a set of values for CommitmentDiscountType within their billing datasets. ## Column ID diff --git a/specification/columns/contractedunitprice.md b/specification/columns/contractedunitprice.md index bbe2fbebf..298904775 100644 --- a/specification/columns/contractedunitprice.md +++ b/specification/columns/contractedunitprice.md @@ -2,7 +2,7 @@ The Contracted Unit Price represents the agreed-upon unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, inclusive of negotiated discounts, if present, while excluding negotiated commitment-based discounts or any other discounts. This price is denominated in the [Billing Currency](#billingcurrency). The Contracted Unit Price is commonly used for calculating savings based on negotiation activities. If negotiated discounts are not applicable, the Contracted Unit Price defaults to the [List Unit Price](#listunitprice). -The ContractedUnitPrice column SHOULD be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ContractedUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost). +The ContractedUnitPrice column MUST be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ContractedUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost). ## Column ID diff --git a/specification/columns/listunitprice.md b/specification/columns/listunitprice.md index 3a1f79d4c..1f2c423e7 100644 --- a/specification/columns/listunitprice.md +++ b/specification/columns/listunitprice.md @@ -2,7 +2,7 @@ The List Unit Price represents the suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, exclusive of any discounts. This price is denominated in the [Billing Currency](#billingcurrency). The List Unit Price is commonly used for calculating savings based on various rate optimization activities. -The ListUnitPrice column SHOULD be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ListUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost). +The ListUnitPrice column MUST be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ListUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost). ## Column ID diff --git a/specification/columns/pricingcategory.md b/specification/columns/pricingcategory.md index 65c42fd8f..f119ea223 100644 --- a/specification/columns/pricingcategory.md +++ b/specification/columns/pricingcategory.md @@ -4,7 +4,7 @@ Pricing Category describes the pricing model used for a charge at the time of us The PricingCategory column adheres to the following requirements: -* PricingCategory SHOULD be present in the billing data when the provider supports more than one pricing category across all SKUs and MUST be of type String. +* PricingCategory MUST be present in the billing data when the provider supports more than one pricing category across all SKUs and MUST be of type String. * PricingCategory MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MUST be null for other ChargeCategory values. * PricingCategory MUST be one of the allowed values. * PricingCategory MUST be "On-Demand" when pricing is predetermined at the standard rate for the [billing account](#glossary:billing-account). diff --git a/specification/columns/regionid.md b/specification/columns/regionid.md index 85174257d..546c83670 100644 --- a/specification/columns/regionid.md +++ b/specification/columns/regionid.md @@ -2,7 +2,7 @@ A Region ID is a provider-assigned identifier for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. The region is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. -The RegionId column SHOULD be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionId values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. +The RegionId column MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionId values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. ## Column ID diff --git a/specification/columns/regionname.md b/specification/columns/regionname.md index 588c5b8f3..6de81ec16 100644 --- a/specification/columns/regionname.md +++ b/specification/columns/regionname.md @@ -2,7 +2,7 @@ Region Name is a provider-assigned display name for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. Region Name is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. -The RegionName column SHOULD be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionName values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. +The RegionName column MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionName values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. ## Column ID diff --git a/specification/columns/resourceid.md b/specification/columns/resourceid.md index c4b1ab06c..85bd08058 100644 --- a/specification/columns/resourceid.md +++ b/specification/columns/resourceid.md @@ -2,7 +2,7 @@ A Resource ID is an identifier assigned to a [*resource*](#glossary:resource) by the provider. The Resource ID is commonly used for cost reporting, analysis, and allocation scenarios. -The ResourceId column SHOULD be present in the billing data when the provider supports billing based on provisioned resources. This column MUST be of type String. The ResourceId value MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource*. ResourceId MUST appear in the cost data if an identifier is assigned to a *resource* by the provider. ResourceId SHOULD be a fully-qualified identifier that ensures global uniqueness within the provider. +The ResourceId column MUST be present in the billing data when the provider supports billing based on provisioned resources. This column MUST be of type String. The ResourceId value MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource*. ResourceId MUST appear in the cost data if an identifier is assigned to a *resource* by the provider. ResourceId SHOULD be a fully-qualified identifier that ensures global uniqueness within the provider. ## Column ID diff --git a/specification/columns/resourcename.md b/specification/columns/resourcename.md index 0d44855cf..4ebf817bc 100644 --- a/specification/columns/resourcename.md +++ b/specification/columns/resourcename.md @@ -2,7 +2,7 @@ The Resource Name is a display name assigned to a [*resource*](#glossary:resource). It is commonly used for cost analysis, reporting, and allocation scenarios. -The ResourceName column SHOULD be present in the billing data when the provider supports billing based on provisioned resources. This column MUST be of type String. The ResourceName value MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource* or because a display name cannot be assigned to a *resource*. ResourceName MUST NOT be null if a display name can be assigned to a *resource*. *Resources* not provisioned interactively or only have a system-generated [ResourceId](#resourceid) MUST NOT duplicate the same value as the ResourceName. +The ResourceName column MUST be present in the billing data when the provider supports billing based on provisioned resources. This column MUST be of type String. The ResourceName value MAY be a nullable column as some cost data [*rows*](#glossary:row) may not be associated with a *resource* or because a display name cannot be assigned to a *resource*. ResourceName MUST NOT be null if a display name can be assigned to a *resource*. *Resources* not provisioned interactively or only have a system-generated [ResourceId](#resourceid) MUST NOT duplicate the same value as the ResourceName. ## Column ID diff --git a/specification/columns/resourcetype.md b/specification/columns/resourcetype.md index 54e7eabae..2ca3b547a 100644 --- a/specification/columns/resourcetype.md +++ b/specification/columns/resourcetype.md @@ -2,7 +2,7 @@ Resource Type describes the kind of [*resource*](#glossary:resource) the charge applies to. A Resource Type is commonly used for scenarios like identifying cost changes in groups of similar *resources* and may include values like Virtual Machine, Data Warehouse, and Load Balancer. -The ResourceType column SHOULD be present in the billing data when the provider supports billing based on provisioned resources and supports assigning a type for resources. This column MUST be of type String and MUST NOT be null when a corresponding [ResourceId](#resourceid) is not null. When a corresponding ResourceId value is null, the ResourceType column value MUST also be null. Providers MUST use a consistent value format and a set of values for ResourceType values within their billing datasets. +The ResourceType column MUST be present in the billing data when the provider supports billing based on provisioned resources and supports assigning a type for resources. This column MUST be of type String and MUST NOT be null when a corresponding [ResourceId](#resourceid) is not null. When a corresponding ResourceId value is null, the ResourceType column value MUST also be null. Providers MUST use a consistent value format and a set of values for ResourceType values within their billing datasets. ## Column ID diff --git a/specification/columns/skuid.md b/specification/columns/skuid.md index 80f490ecc..2ef0bd240 100644 --- a/specification/columns/skuid.md +++ b/specification/columns/skuid.md @@ -2,7 +2,7 @@ A SKU ID is a unique identifier that defines a provider-supported construct for organizing properties that are common across one or more [*SKU Prices*](#glossary:sku-price). SKU ID can be referenced on a catalog or [*price list*](#glossary:price-list) published by a provider to look up detailed information about the SKU. The composition of the properties associated with the SKU ID may differ across providers. Some providers may not support the [*SKU*](#glossary:sku) construct and instead associate all such properties directly with the *SKU Price*. SKU ID is commonly used for analyzing cost based on *SKU*-related properties above the pricing constructs. -The SkuId column SHOULD be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. The SkuId MUST NOT be null when [SkuPriceId](#skupriceid) is not null. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. +The SkuId column MUST be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. The SkuId MUST NOT be null when [SkuPriceId](#skupriceid) is not null. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. ## Column ID diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index 42577a331..e5c174f2b 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -21,7 +21,7 @@ A unique identifier that defines the unit price used to calculate the charge. | Constraint | Value | | :--------------- | :------------- | | Column type | Dimension | -| Feature level | Conditional | +| Feature level | Mandatory | | Allows nulls | True | | Data type | String | | Value format | \ | diff --git a/specification/columns/subaccountid.md b/specification/columns/subaccountid.md index 53df2f73b..9f85ffda2 100644 --- a/specification/columns/subaccountid.md +++ b/specification/columns/subaccountid.md @@ -2,7 +2,7 @@ A Sub Account ID is a provider-assigned identifier assigned to a [*sub account*](#glossary:sub-account). Sub Account ID is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. -The SubAccountId column SHOULD be present in the billing data when the provider supports a *sub account* construct. This column MUST be of type String. If a charge does not apply to a *sub account*, the SubAccountId column MUST be null. +The SubAccountId column MUST be present in the billing data when the provider supports a *sub account* construct. This column MUST be of type String. If a charge does not apply to a *sub account*, the SubAccountId column MUST be null. See [Appendix: Grouping constructs for resources or services](#groupingconstructsforresourcesorservices) for details and examples of the different grouping constructs supported by FOCUS. diff --git a/specification/columns/subaccountname.md b/specification/columns/subaccountname.md index f0c636811..e5428658d 100644 --- a/specification/columns/subaccountname.md +++ b/specification/columns/subaccountname.md @@ -2,7 +2,7 @@ A Sub Account Name is a display name assigned to a [*sub account*](#glossary:sub-account). Sub account Name is commonly used for scenarios like grouping based on organizational constructs, access management needs, and cost allocation strategies. -The SubAccountName column SHOULD be present in the billing data when the provider supports a *sub account* construct. This column MUST be of type String. If a charge does not apply to a *sub account*, the SubAccountName column MUST be null. +The SubAccountName column MUST be present in the billing data when the provider supports a *sub account* construct. This column MUST be of type String. If a charge does not apply to a *sub account*, the SubAccountName column MUST be null. See [Appendix: Grouping constructs for resources or services](#groupingconstructsforresourcesorservices) for details and examples of the different grouping constructs supported by FOCUS. diff --git a/specification/columns/tags.md b/specification/columns/tags.md index c34b5b63f..3795f8139 100644 --- a/specification/columns/tags.md +++ b/specification/columns/tags.md @@ -6,7 +6,7 @@ A tag becomes [*finalized*](#glossary:finalized-tag) when a single value is sele The Tags column adheres to the following requirements: -* The Tags column SHOULD be present in the billing data when the provider supports setting user or provider-defined tags. +* The Tags column MUST be present in the billing data when the provider supports setting user or provider-defined tags. * The Tags column MUST contain user-defined and provider-defined tags. * The Tags column MUST only contain finalized tags. * The Tags column MUST be in [Key-Value Format](#key-valueformat). diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md index 0cd552757..879fe325f 100644 --- a/specification/columns/usagequantity.md +++ b/specification/columns/usagequantity.md @@ -2,7 +2,7 @@ The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)) and focuses on *resource* and *service* consumption, not pricing and cost. -UsageQuantity column SHOULD be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. +UsageQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. ## Column ID diff --git a/specification/columns/usageunit.md b/specification/columns/usageunit.md index 7abc49170..a9b40264a 100644 --- a/specification/columns/usageunit.md +++ b/specification/columns/usageunit.md @@ -2,7 +2,7 @@ The Usage Unit represents a provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service). Usage Unit complements the [Usage Quantity](#usagequantity) metric. It is often listed at a finer granularity or over a different time interval when compared to the [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. -The UsageUnit column SHOULD be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. UsageUnit MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. +The UsageUnit column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. UsageUnit MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. ## Column ID From 4996e260b002aaaeee06cc8eda713923301f75a7 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Thu, 11 Apr 2024 16:31:47 -0700 Subject: [PATCH 31/65] Update specification/columns/commitmentdiscountcategory.md Ok, this was the column that I took as example and it was in the PR but now I realized that I should reverse back to the simple changes. Co-authored-by: Udam Dewaraja --- specification/columns/commitmentdiscountcategory.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/specification/columns/commitmentdiscountcategory.md b/specification/columns/commitmentdiscountcategory.md index 8f89c748b..cafcc4a51 100644 --- a/specification/columns/commitmentdiscountcategory.md +++ b/specification/columns/commitmentdiscountcategory.md @@ -2,13 +2,7 @@ Commitment Discount Category indicates whether the [*commitment-based discount*](#glossary:commitment-based-discount) identified in the CommitmentDiscountId column is based on usage quantity or cost (aka "spend"). -The CommitmentDiscountCategory column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String data and MUST contain one of the allowed enumerated values: -* "Spend": Commitment-based discounts that require a predetermined amount of spend. -* "Usage": Commitment-based discounts that require a predetermined amount of usage. - -Additionally: - IF [CommitmentDiscountId](#commitmentdiscountid) is null, THEN CommitmentDiscountCategory MUST also be null. - IF [CommitmentDiscountId](#commitmentdiscountid) is not null, THEN CommitmentDiscountCategory MUST NOT be null and adhere to the allowed enumerated values. +The CommitmentDiscountCategory column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. The CommitmentDiscountCategory MUST be one of the allowed values. ## Column ID From 1ddae6b111478193be1c5d7b39ce8e4515c82995 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Thu, 11 Apr 2024 16:50:42 -0700 Subject: [PATCH 32/65] Update skupriceid.md Change to conditional as agreed by the group --- specification/columns/skupriceid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index e5c174f2b..139a71c84 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -21,7 +21,7 @@ A unique identifier that defines the unit price used to calculate the charge. | Constraint | Value | | :--------------- | :------------- | | Column type | Dimension | -| Feature level | Mandatory | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | From 3e3b552d890526037f3914edefcea42827144fe2 Mon Sep 17 00:00:00 2001 From: Alex Hullah Date: Fri, 12 Apr 2024 15:37:41 +0000 Subject: [PATCH 33/65] quick fix for failing buildpdf on availabilityzone.md --- specification/columns/availabilityzone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/availabilityzone.md b/specification/columns/availabilityzone.md index d998b5544..e8dfb3681 100644 --- a/specification/columns/availabilityzone.md +++ b/specification/columns/availabilityzone.md @@ -2,7 +2,7 @@ An [*availability zone*](#glossary:availability-zone) is a provider-assigned identifier for a physically separated and isolated area within a Region that provides high availability and fault tolerance. Availability Zone is commonly used for scenarios like analyzing cross-zone data transfer usage and the corresponding cost based on where [*resources*](#glossary:resource) are deployed. -The AvailabilityZone column is RECOMMENDED to be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. +The AvailabilityZone column is RECOMMENDED to be present in the billing data when the provider supports deploying resources or services within an *availability zone*. This column MUST be of type String and MAY contain null values when a charge is not specific to an *availability zone*. ## Column ID From 784e079c7c3261bdda1c29be0393f2a8deacaa7a Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Fri, 12 Apr 2024 12:22:48 -0700 Subject: [PATCH 34/65] Remove unnecessary change in spacing --- specification/columns/skupriceid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index 139a71c84..42577a331 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -21,7 +21,7 @@ A unique identifier that defines the unit price used to calculate the charge. | Constraint | Value | | :--------------- | :------------- | | Column type | Dimension | -| Feature level | Conditional | +| Feature level | Conditional | | Allows nulls | True | | Data type | String | | Value format | \ | From 19be6c63268f69b3592f9f6885cb715552e84004 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Fri, 12 Apr 2024 17:35:55 -0700 Subject: [PATCH 35/65] Update skupriceid.md Statement provided by Irena after TF1&2 meeting on Friday, April 12 --- specification/columns/skupriceid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index 42577a331..78c73341a 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -2,7 +2,7 @@ A SKU Price ID is a unique identifier that defines the unit price used to calculate the charge. SKU Price ID can be referenced on a [*price list*](#glossary:price-list) published by a provider to look up detailed information, including a corresponding list unit price. The composition of the properties associated with the SKU Price ID may differ across providers. SKU Price ID is commonly used for analyzing cost based on pricing properties such as Terms and Tiers. -The SkuPriceId column MUST be present in the billing data. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage" and [ChargeClass](#chargeclass) is "Regular". The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Credit" or "Adjustment" and the charge is associated with a specific SkuPriceId. SkuPriceId MUST NOT be null when [ChargeClass](#chargeclass) is "Correction" and the correction is associated with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. +The SkuPriceId column MUST be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage" and [ChargeClass](#chargeclass) is "Regular". The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Credit" or "Adjustment" and the charge is associated with a specific SkuPriceId. SkuPriceId MUST NOT be null when [ChargeClass](#chargeclass) is "Correction" and the correction is associated with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. ## Column ID From 87f4c79c11118843327ad404fcee1b0e03251284 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Fri, 19 Apr 2024 09:28:14 +1000 Subject: [PATCH 36/65] Metadata structure simple (#390) Adding Metadata section with initial set of requirements for FOCUS data generators Approved at the Apr 18th Weekly Meeting --------- Signed-off-by: Mike Fuller Co-authored-by: Riley Jenkins Co-authored-by: Michael Flanakin Co-authored-by: Alex Hullah Co-authored-by: Udam Dewaraja --- .../data_generator/data_generator.mdpp | 7 + .../metadata/data_generator/datagenerator.md | 17 +++ .../data_generator/datageneratorversion.md | 17 +++ .../data_generator/providertagprefix.md | 17 +++ specification/metadata/metadata.mdpp | 6 + .../column_definition/column_definition.mdpp | 10 ++ .../schema/column_definition/columnname.md | 17 +++ .../schema/column_definition/datatype.md | 17 +++ .../schema/column_definition/numberscale.md | 17 +++ .../column_definition/numericprecision.md | 17 +++ .../column_definition/stringencoding.md | 17 +++ .../column_definition/stringmaxlength.md | 17 +++ specification/metadata/schema/creationdate.md | 17 +++ specification/metadata/schema/focusversion.md | 17 +++ specification/metadata/schema/schema.mdpp | 7 + specification/spec.mdpp | 4 + supporting_content/metadata/metadata.md | 127 ++++++++++++++++++ 17 files changed, 348 insertions(+) create mode 100644 specification/metadata/data_generator/data_generator.mdpp create mode 100644 specification/metadata/data_generator/datagenerator.md create mode 100644 specification/metadata/data_generator/datageneratorversion.md create mode 100644 specification/metadata/data_generator/providertagprefix.md create mode 100644 specification/metadata/metadata.mdpp create mode 100644 specification/metadata/schema/column_definition/column_definition.mdpp create mode 100644 specification/metadata/schema/column_definition/columnname.md create mode 100644 specification/metadata/schema/column_definition/datatype.md create mode 100644 specification/metadata/schema/column_definition/numberscale.md create mode 100644 specification/metadata/schema/column_definition/numericprecision.md create mode 100644 specification/metadata/schema/column_definition/stringencoding.md create mode 100644 specification/metadata/schema/column_definition/stringmaxlength.md create mode 100644 specification/metadata/schema/creationdate.md create mode 100644 specification/metadata/schema/focusversion.md create mode 100644 specification/metadata/schema/schema.mdpp create mode 100644 supporting_content/metadata/metadata.md diff --git a/specification/metadata/data_generator/data_generator.mdpp b/specification/metadata/data_generator/data_generator.mdpp new file mode 100644 index 000000000..89a05a373 --- /dev/null +++ b/specification/metadata/data_generator/data_generator.mdpp @@ -0,0 +1,7 @@ +# Data Generator + +The FOCUS metadata about the generator of the FOCUS data. + +!INCLUDE "datagenerator.md",1 +!INCLUDE "datageneratorversion.md",1 +!INCLUDE "providertagprefix.md",1 diff --git a/specification/metadata/data_generator/datagenerator.md b/specification/metadata/data_generator/datagenerator.md new file mode 100644 index 000000000..a731c5999 --- /dev/null +++ b/specification/metadata/data_generator/datagenerator.md @@ -0,0 +1,17 @@ +# Data Generator + +Human readable name of the entity that is generating the data. + +The DataGenerator MUST be provided in the metadata. DataGenerator MUST be of type String and MUST NOT contain null values. The DataGenerator SHOULD be easily associated with the provider who generated the FOCUS dataset. + +## Metadata ID + +DataGenerator + +## Metadata Name + +Data Generator + +## Introduced (version) + +1.0 diff --git a/specification/metadata/data_generator/datageneratorversion.md b/specification/metadata/data_generator/datageneratorversion.md new file mode 100644 index 000000000..1d3edf671 --- /dev/null +++ b/specification/metadata/data_generator/datageneratorversion.md @@ -0,0 +1,17 @@ +# Data Generator Version + +A version specific to the data generator for providers which support multiple FOCUS datasets with different provider columns, or for providers who release multiple versions of their generated datasets between FOCUS Versions. + +The DataGeneratorVersion MUST be provided in the metadata, when multiple datasets using the same FOCUS version are provided with different provider columns. DataGeneratorVersion MUST be of type String and MUST NOT contain null values. The DataGeneratorVersion is RECOMMENDED to use semantic versioning. + +## Metadata ID + +DataGeneratorVersion + +## Metadata Name + +Data Generator Version + +## Introduced (version) + +1.0 diff --git a/specification/metadata/data_generator/providertagprefix.md b/specification/metadata/data_generator/providertagprefix.md new file mode 100644 index 000000000..61b98e777 --- /dev/null +++ b/specification/metadata/data_generator/providertagprefix.md @@ -0,0 +1,17 @@ +# Provider Tag Prefixes + +The Provider Tag Prefixes defines the list of prefixes used in the tag name of provider-defined [tags](#tags). This metadata is useful for the consumer to identify which tags are provider-defined vs user-defined. + +The ProviderTagPrefixes SHOULD be provided when the provider supports provider-defined tags. The ProviderTagPrefix MUST be of type Array of Strings. The ProviderTagPrefixes SHOULD be easily associated with the provider who generated the FOCUS dataset. + +## Metadata ID + +ProviderTagPrefixes + +## Metadata Name + +Provider Tag Prefixes + +## Introduced (version) + +1.0 diff --git a/specification/metadata/metadata.mdpp b/specification/metadata/metadata.mdpp new file mode 100644 index 000000000..4b1b22fe0 --- /dev/null +++ b/specification/metadata/metadata.mdpp @@ -0,0 +1,6 @@ +# Metadata + +The FOCUS specification defines a metadata structure that is to be supplied by data providers to facilitate practitioners use of FOCUS data. This meta data includes general information about the data generator and the schema of the FOCUS dataset. FOCUS Metadata SHOULD be provided in a format that is accessible programmatically, such as: a file, website, api, table. + +!INCLUDE "data_generator/data_generator.mdpp",1 +!INCLUDE "schema/schema.mdpp",1 diff --git a/specification/metadata/schema/column_definition/column_definition.mdpp b/specification/metadata/schema/column_definition/column_definition.mdpp new file mode 100644 index 000000000..668103b04 --- /dev/null +++ b/specification/metadata/schema/column_definition/column_definition.mdpp @@ -0,0 +1,10 @@ +# Column Definition + +The FOCUS metadata schema column definition provides a list of the columns present in the FOCUS dataset along with metadata about the columns. + +!INCLUDE "columnname.md",1 +!INCLUDE "datatype.md",1 +!INCLUDE "stringencoding.md",1 +!INCLUDE "stringmaxlength.md",1 +!INCLUDE "numericprecision.md",1 +!INCLUDE "numberscale.md",1 diff --git a/specification/metadata/schema/column_definition/columnname.md b/specification/metadata/schema/column_definition/columnname.md new file mode 100644 index 000000000..cc9ff728b --- /dev/null +++ b/specification/metadata/schema/column_definition/columnname.md @@ -0,0 +1,17 @@ +# Column Name + +The name of the column provided in the FOCUS dataset. + +The ColumnName MUST be provided in the FOCUS Metadata schema. ColumnName MUST be of type String and MUST NOT contain null values. + +## Metadata ID + +ColumnName + +## Metadata Name + +Column Name + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/column_definition/datatype.md b/specification/metadata/schema/column_definition/datatype.md new file mode 100644 index 000000000..bd099443d --- /dev/null +++ b/specification/metadata/schema/column_definition/datatype.md @@ -0,0 +1,17 @@ +# Data Type + +The data type of the column provided in the FOCUS dataset. + +The DataType MUST be provided in the FOCUS Metadata schema. DataType MUST be of type String and MUST NOT contain null values. + +## Metadata ID + +DataType + +## Metadata Name + +Data Type + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/column_definition/numberscale.md b/specification/metadata/schema/column_definition/numberscale.md new file mode 100644 index 000000000..4602e7058 --- /dev/null +++ b/specification/metadata/schema/column_definition/numberscale.md @@ -0,0 +1,17 @@ +# Number Scale + +The number scale of the data provides the maximum number of digits after the decimal point in decimal numbers. + +NumberScale SHOULD be provided in the FOCUS Metadata schema for Decimal columns. NumberScale MUST be of type Integer and MUST NOT contain null values. + +## Metadata ID + +NumberScale + +## Metadata Name + +Number Scale + +## Introduced (version) + +1.0 \ No newline at end of file diff --git a/specification/metadata/schema/column_definition/numericprecision.md b/specification/metadata/schema/column_definition/numericprecision.md new file mode 100644 index 000000000..1ac35d95c --- /dev/null +++ b/specification/metadata/schema/column_definition/numericprecision.md @@ -0,0 +1,17 @@ +# Numeric Precision + +Numeric Precision is the maximum number of digits for the values in the column. + +NumericPrecision SHOULD be provided in the FOCUS Metadata schema for Numeric Format columns. NumericPrecision MUST be of type Integer and MUST NOT contain null values. + +## Metadata ID + +NumericPrecision + +## Metadata Name + +Numeric Precision + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/column_definition/stringencoding.md b/specification/metadata/schema/column_definition/stringencoding.md new file mode 100644 index 000000000..cb9f870a1 --- /dev/null +++ b/specification/metadata/schema/column_definition/stringencoding.md @@ -0,0 +1,17 @@ +# String Encoding + +The string encoding scheme of the column provided in the FOCUS dataset. + +StringEncoding SHOULD be provided in the FOCUS Metadata schema when it is required to know this information in order to successfully read the data. StringEncoding MUST be of type String and MUST NOT contain null values. + +## Metadata ID + +StringEncoding + +## Metadata Name + +StringEncoding + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/column_definition/stringmaxlength.md b/specification/metadata/schema/column_definition/stringmaxlength.md new file mode 100644 index 000000000..69a74e3e0 --- /dev/null +++ b/specification/metadata/schema/column_definition/stringmaxlength.md @@ -0,0 +1,17 @@ +# String Max Length + +The string max length of the data that can be stored in the column. + +StringMaxLength SHOULD be provided in the FOCUS Metadata schema for String columns. StringMaxLength MUST be of type Integer and MUST NOT contain null values. + +## Metadata ID + +StringMaxLength + +## Metadata Name + +String Max Length + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/creationdate.md b/specification/metadata/schema/creationdate.md new file mode 100644 index 000000000..6c5ed6bc1 --- /dev/null +++ b/specification/metadata/schema/creationdate.md @@ -0,0 +1,17 @@ +# Creation Date + +Date the schema was created. + +The CreationDate MUST be present in the metadata. This MUST be of type Date/Time and MUST NOT contain null values. CreationDate MUST conform to [Date/Time Format](#date/timeformat). + +## Metadata ID + +CreationDate + +## Metadata Name + +Creation Date + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/focusversion.md b/specification/metadata/schema/focusversion.md new file mode 100644 index 000000000..c650665bd --- /dev/null +++ b/specification/metadata/schema/focusversion.md @@ -0,0 +1,17 @@ +# FOCUS Version + +The version of FOCUS utilized for building the dataset. + +The FocusVersion MUST be provided in the metadata. FocusVersion MUST be of type String and MUST NOT contain null values. FOCUSVersion MUST match one of the published versions of the FOCUS specification. FocusVersion MUST match the version of the FOCUS specification that the FOCUS dataset conforms to. + +## Metadata ID + +FocusVersion + +## Metadata Name + +FOCUS Version + +## Introduced (version) + +1.0 diff --git a/specification/metadata/schema/schema.mdpp b/specification/metadata/schema/schema.mdpp new file mode 100644 index 000000000..b4d9d72ac --- /dev/null +++ b/specification/metadata/schema/schema.mdpp @@ -0,0 +1,7 @@ +# Schema + +Each FOCUS dataset must have a metadata about the schema associated with it. The schema metadata provides information about the structure of the data provided. + +!INCLUDE "creationdate.md",1 +!INCLUDE "focusversion.md",1 +!INCLUDE "column_definition/column_definition.mdpp",1 diff --git a/specification/spec.mdpp b/specification/spec.mdpp index f8f659f72..d15f97372 100644 --- a/specification/spec.mdpp +++ b/specification/spec.mdpp @@ -35,6 +35,10 @@ FOCUS is an open-source specification for billing data. It defines a common sche
+!INCLUDE "metadata/metadata.mdpp",1 + +
+ !INCLUDE "use_case_library.md",1
diff --git a/supporting_content/metadata/metadata.md b/supporting_content/metadata/metadata.md new file mode 100644 index 000000000..e6406c6b9 --- /dev/null +++ b/supporting_content/metadata/metadata.md @@ -0,0 +1,127 @@ +# Metadata Example API + +## Example Data Generator Metadata + +In this example the billing data generator's FOCUS metadata API is queried for the provider metadata. + +#### Endpoint: /FOCUS/metadata/data_generator +#### Example Request: + + Method: GET + Endpoint : /FOCUS/metadata/data_generator +#### + +#### Response +``` +{ + "DataGenerator": "awesome_corp", + "DataGeneratorVersion": "1.0.1", + "ProviderTagPrefixes": ["awecorp", "ac"] +}` +``` + +## Example Schema Metadata + +In this example, the billing data includes two different structures of data. An older schema for data previously provided, and a newer schema for more recent data. Both schemas metata is provided. + +### API + +#### Endpoint: /FOCUS/metadata/schemas +#### Example Request: + endpoint: /FOCUS/metadata/schemas + method: GET +#### + +#### Response +``` +{ + [ + { + "FocusVersion": "1.0", + "name": "my original schema", + "CreationDate": "2024-01-01T12:01:03.083z" + "schema_column_endpoint": /FOCUS/metadata/schemas/1234/columns + }, + { + "FocusVersion": "1.1", + "name": "my new schema", + "CreationDate": "2024-07-01T12:00:04.001z" + "schema_column_endpoint": /FOCUS/metadata/schemas/2345/columns + } + ] +} +``` + +## Example Schema Column Definition Metadata + +In this example the billing data generator's FOCUS metadata API is queried for the schema_id = 1234. + +### API Schema + +#### Endpoint: /FOCUS/metadata/schema/{id}/columns +#### Example Request: + + Method: GET + Endpoint : /FOCUS/metadata/schema/1234/columns +#### + +#### Response +``` +{ + "FOCUS_version": "1.0", + "name": "my original schema", + "CreationDate": "2024-01-01T12:01:03.083z" + "ColumnDefinition": [ + { + ColumnName: "BillingAccountId", + DataType: "STRING" + StringMaxLength: 64, + StringEncoding: "UTF-8" + }, + { + ColumnName: "BillingAccountName", + DataType: "STRING" + StringMaxLength: 64, + StringEncoding: "UTF-8" + }, + { + ColumnName: "ChargePeriodStart", + DataType: "DATETIME" + }, + { + ColumnName: "ChargePeriodEnd", + DataType: "DATETIME" + }, + { + ColumnName: "BilledCost", + DataType: "DECIMAL", + NumericPrecision: 20, + NumberScale: 10 + }, + { + ColumnName: "EffecitiveCost", + DataType: "DECIMAL", + NumericPrecision: 20, + NumberScale: 10 + }, + ] +}` +``` + +## Example Schema Reference Metadata + +In this example, when the provider returns the FOCUS data they include in the response a reference to the schema utilized in the FOCUS dataset. + +#### Example Request: + Endpoint: /FOCUS/data/2024010001 + Method: GET +#### + +#### Response +``` +{ + "data": [ + ... + ] +} +``` \ No newline at end of file From e632dacbb1c6a693e18884be47dd540b9373bfd8 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Thu, 18 Apr 2024 10:14:19 -0700 Subject: [PATCH 37/65] adjustments to the timeline based on where we are --- RELEASE-PLANNING.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/RELEASE-PLANNING.md b/RELEASE-PLANNING.md index b0cdb69f2..05dfdabb4 100644 --- a/RELEASE-PLANNING.md +++ b/RELEASE-PLANNING.md @@ -17,27 +17,27 @@ This estimated time line was approved by the Members working group on the Feb 29 Opportunity for everyone to review what has been agreed upon in the working-draft branch.
Lock scope for v1.0. - Mar 12 - Apr 22 + Mar 12 - Apr 25 Drive v1.0 milestone issues to completion Incoming issues will be prioritized by maintainers. Only P0 and some P1 issues will get added to the v1.0 milestone. Prioritization will take voting and comments in issues into consideration - Apr 23 - Apr 30 + Apr 25 - May 02 Final Consistency Review Freeze working-draft.
Final review, only expecting editorial comments. - - May 2 - Release Candidate Approve by the WG Members - - May 2 - May 31 IPR Review Members may exclude any Essential Claims from their licensing commitments during this period. - Jun 3 + June 6 + Release Candidate Approve by the WG Members + + + + Jun 6 Steering Committee Ratifies the Release From c0c170c4b5ad001034b8a0e16a7bf9ec6f78777d Mon Sep 17 00:00:00 2001 From: Irena Jurica Date: Tue, 23 Apr 2024 02:19:24 +0200 Subject: [PATCH 38/65] FOCUS #104: ConsistencyHandling or StringFormat attribute (#396) - Adding StringFormat attribute specification and supporting content - Removing current references to value-format consistency requirements from the following columns: - RegionId - RegionName - ResourceType - CommitmentDiscountType - Making a small adjustment in the NumericFormat specification --------- Co-authored-by: Alex Hullah Co-authored-by: Udam Dewaraja --- specification/attributes/attributes.mdpp | 1 + .../attributes/column_naming_convention.md | 2 +- .../attributes/currency_code_format.md | 2 +- specification/attributes/datetime_format.md | 2 +- specification/attributes/key_value_format.md | 2 +- specification/attributes/null_handling.md | 2 +- specification/attributes/numeric_format.md | 4 +- specification/attributes/string_handling.md | 32 +++++++ specification/attributes/unit_format.md | 2 +- .../columns/commitmentdiscounttype.md | 2 +- specification/columns/regionid.md | 2 +- specification/columns/regionname.md | 2 +- specification/columns/resourcetype.md | 2 +- .../attributes/string_handling.md | 88 +++++++++++++++++++ 14 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 specification/attributes/string_handling.md create mode 100644 supporting_content/attributes/string_handling.md diff --git a/specification/attributes/attributes.mdpp b/specification/attributes/attributes.mdpp index bf6295459..a7a8508b7 100644 --- a/specification/attributes/attributes.mdpp +++ b/specification/attributes/attributes.mdpp @@ -12,4 +12,5 @@ for data granularity, recency, frequency, etc. Requirements defined in attribute !INCLUDE "key_value_format.md",1 !INCLUDE "null_handling.md",1 !INCLUDE "numeric_format.md",1 +!INCLUDE "string_handling.md",1 !INCLUDE "unit_format.md",1 diff --git a/specification/attributes/column_naming_convention.md b/specification/attributes/column_naming_convention.md index 57fa27527..ebfc83b6c 100644 --- a/specification/attributes/column_naming_convention.md +++ b/specification/attributes/column_naming_convention.md @@ -2,7 +2,7 @@ Column IDs provided in cost data following a consistent naming convention reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. -All columns defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification MUST follow the naming requirements listed below. +All columns defined in the FOCUS specification MUST follow the naming requirements listed below. ## Attribute ID diff --git a/specification/attributes/currency_code_format.md b/specification/attributes/currency_code_format.md index 6e728a497..b9811ca3b 100644 --- a/specification/attributes/currency_code_format.md +++ b/specification/attributes/currency_code_format.md @@ -2,7 +2,7 @@ Columns that contain currency information in cost data following a consistent format reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. -All columns capturing a currency value, defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification, MUST follow the requirements listed below. Custom currency-related columns SHOULD also follow the same formatting requirements. +All columns capturing a currency value, defined in the FOCUS specification, MUST follow the requirements listed below. Custom currency-related columns SHOULD also follow the same formatting requirements. ## Attribute ID diff --git a/specification/attributes/datetime_format.md b/specification/attributes/datetime_format.md index 4df5623da..895ec64bd 100644 --- a/specification/attributes/datetime_format.md +++ b/specification/attributes/datetime_format.md @@ -2,7 +2,7 @@ Columns that provide date and time information conforming to specified rules and formatting requirements ensure clarity, accuracy, and ease of interpretation for both humans and systems. -All columns capturing a date/time value, defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification, MUST follow the formatting requirements listed below. Custom date/time-related columns SHOULD also follow the same formatting requirements. +All columns capturing a date/time value, defined in the FOCUS specification, MUST follow the formatting requirements listed below. Custom date/time-related columns SHOULD also follow the same formatting requirements. ## Attribute ID diff --git a/specification/attributes/key_value_format.md b/specification/attributes/key_value_format.md index 42beb4b00..06f592efd 100644 --- a/specification/attributes/key_value_format.md +++ b/specification/attributes/key_value_format.md @@ -2,7 +2,7 @@ Columns that provide Key-Value information are often used in place of separate columns for enumerating data which would be inherently sparse and/or without predetermined keys. This consolidates related information and provides more consistency in the schema. Key-value pairs are also referred to as name-value pairs, attribute-value pairs, or field-value pairs. -All key-value related columns defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification MUST follow the key-value formatting requirements listed below. +All key-value related columns defined in the FOCUS specification MUST follow the key-value formatting requirements listed below. ## Attribute ID diff --git a/specification/attributes/null_handling.md b/specification/attributes/null_handling.md index bb309e3ec..3805d1fc2 100644 --- a/specification/attributes/null_handling.md +++ b/specification/attributes/null_handling.md @@ -2,7 +2,7 @@ Cost data [*rows*](#glossary:row) that don't have a value that can be presented for a column must be handled in a consistent way to reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. -All columns defined in the [FOCUS](#glossary:finops-cost-and-usage-specification) specification MUST follow the null handling requirements listed below. Custom columns SHOULD also follow the same formatting requirements. +All columns defined in the FOCUS specification MUST follow the null handling requirements listed below. Custom columns SHOULD also follow the same formatting requirements. ## Attribute ID diff --git a/specification/attributes/numeric_format.md b/specification/attributes/numeric_format.md index 9f84daacc..a187f3233 100644 --- a/specification/attributes/numeric_format.md +++ b/specification/attributes/numeric_format.md @@ -1,8 +1,8 @@ # Numeric Format -Columns that provide numeric values conforming to specified rules and formatting requirements ensure clarity, accuracy, and ease of interpretation for humans and systems. The [FOCUS](#glossary:finops-cost-and-usage-specification) specification does not require a specific level of precision for numeric values. The level of precision required for a given column is determined by the provider and should be part of a data definition published by the provider. +Columns that provide numeric values conforming to specified rules and formatting requirements ensure clarity, accuracy, and ease of interpretation for humans and systems. The FOCUS specification does not require a specific level of precision for numeric values. The level of precision required for a given column is determined by the provider and should be part of a data definition published by the provider. -All columns capturing a numeric value, defined in the FOCUS specification, MUST follow the formatting requirements listed below. Provider-generated numeric value capturing columns SHOULD adopt the same format requirements over time. +All columns capturing a numeric value, defined in the FOCUS specification, MUST follow the formatting requirements listed below. Custom numeric value capturing columns SHOULD adopt the same format requirements over time. ## Attribute ID diff --git a/specification/attributes/string_handling.md b/specification/attributes/string_handling.md new file mode 100644 index 000000000..9e554777c --- /dev/null +++ b/specification/attributes/string_handling.md @@ -0,0 +1,32 @@ +# String Handling + +Columns that capture string values conforming to specified requirements foster data integrity, interoperability, and consistency, improve data analysis and reporting, and support reliable data-driven decision-making. + +All columns capturing a string value, defined in the FOCUS specification, MUST follow the requirements listed below. Custom string value capturing columns SHOULD adopt the same requirements over time. + +## Attribute ID + +StringHandling + +## Attribute Name + +String Handling + +## Description + +Requirements for string-capturing columns appearing in billing data. + +## Requirements + +* String values MUST maintain the original casing, spacing, and other relevant consistency factors as specified by providers and end-users. +* [*Charges*](#glossary:charge) to mutable entities (e.g., resource names) MUST be accurately reflected in corresponding *charges* incurred after the change and MUST NOT alter *charges* incurred before the change, preserving data integrity and auditability for all *charge* records. +* Immutable string values that refer to the same entity (e.g., resource identifiers, region identifiers, etc.) MUST remain consistent and unchanged across all [*billing periods*](#glossary:billing-period). +* Empty strings and strings consisting solely of spaces SHOULD NOT be used in not-nullable string columns. + +## Exceptions + +* When a record is provided after a change to a mutable string value and the [ChargeClass](#chargeclass) is "Correction", the record MAY contain the altered value. + +## Introduced (version) + +1.0 diff --git a/specification/attributes/unit_format.md b/specification/attributes/unit_format.md index ab88e5994..c428b8429 100644 --- a/specification/attributes/unit_format.md +++ b/specification/attributes/unit_format.md @@ -2,7 +2,7 @@ Billing data frequently captures data measured in units related to data size, count, time, and other [*dimensions*](#glossary:dimension). The Unit Format attribute provides a standard for expressing units of measure in columns appearing in billing data. -All columns defined in [FOCUS](#glossary:finops-cost-and-usage-specification) specifying Unit Format as a value format MUST follow the requirements listed below. +All columns defined in FOCUS specifying Unit Format as a value format MUST follow the requirements listed below. ## Attribute ID diff --git a/specification/columns/commitmentdiscounttype.md b/specification/columns/commitmentdiscounttype.md index 3248d7b89..5a7ed12c7 100644 --- a/specification/columns/commitmentdiscounttype.md +++ b/specification/columns/commitmentdiscounttype.md @@ -2,7 +2,7 @@ Commitment Discount Type is a provider-assigned name to identify the type of [*commitment-based discount*](#glossary:commitment-based-discount) applied to the [*row*](#glossary:row). -The CommitmentDiscountType column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. Providers MUST use a consistent value format and a set of values for CommitmentDiscountType within their billing datasets. +The CommitmentDiscountType column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. ## Column ID diff --git a/specification/columns/regionid.md b/specification/columns/regionid.md index 546c83670..06742553d 100644 --- a/specification/columns/regionid.md +++ b/specification/columns/regionid.md @@ -2,7 +2,7 @@ A Region ID is a provider-assigned identifier for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. The region is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. -The RegionId column MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionId values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. +The RegionId column MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. ## Column ID diff --git a/specification/columns/regionname.md b/specification/columns/regionname.md index 6de81ec16..40d030876 100644 --- a/specification/columns/regionname.md +++ b/specification/columns/regionname.md @@ -2,7 +2,7 @@ Region Name is a provider-assigned display name for an isolated geographic area where a [*resource*](#glossary:resource) is provisioned or a [*service*](#glossary:service) is provided. Region Name is commonly used for scenarios like analyzing cost and unit prices based on where *resources* are deployed. -The RegionName column MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. RegionName values MUST be consistent within the provider and MUST be the same values used to indicate the region when provisioning or purchasing the *resource* or *service*. +The RegionName column MUST be present in the billing data when the provider supports deploying resources or services within a *region* and MUST be of type String. RegionName MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider and MAY contain null values when a *resource* or *service* is not restricted to an isolated geographic area. ## Column ID diff --git a/specification/columns/resourcetype.md b/specification/columns/resourcetype.md index 2ca3b547a..605d707aa 100644 --- a/specification/columns/resourcetype.md +++ b/specification/columns/resourcetype.md @@ -2,7 +2,7 @@ Resource Type describes the kind of [*resource*](#glossary:resource) the charge applies to. A Resource Type is commonly used for scenarios like identifying cost changes in groups of similar *resources* and may include values like Virtual Machine, Data Warehouse, and Load Balancer. -The ResourceType column MUST be present in the billing data when the provider supports billing based on provisioned resources and supports assigning a type for resources. This column MUST be of type String and MUST NOT be null when a corresponding [ResourceId](#resourceid) is not null. When a corresponding ResourceId value is null, the ResourceType column value MUST also be null. Providers MUST use a consistent value format and a set of values for ResourceType values within their billing datasets. +The ResourceType column MUST be present in the billing data when the provider supports billing based on provisioned resources and supports assigning a type for resources. This column MUST be of type String and MUST NOT be null when a corresponding [ResourceId](#resourceid) is not null. When a corresponding ResourceId value is null, the ResourceType column value MUST also be null. ## Column ID diff --git a/supporting_content/attributes/string_handling.md b/supporting_content/attributes/string_handling.md new file mode 100644 index 000000000..541d1c1d6 --- /dev/null +++ b/supporting_content/attributes/string_handling.md @@ -0,0 +1,88 @@ +# String Handling + +## Example usage scenarios + +Sample known issues observed in billing data and other data sources for various scenarios: + +| Provider | Data set | Scenario | +| --------- | ------------------------ | ------------------------------------------------------------------------------------------- | +| AWS | CUR | ? | +| GCP | Big Query Billing Export | ? | +| Microsoft | Cost Details | Known issue with ResourceId casing | +| OCI | Cost reports | Known issue with PricingUnits casing - Cost reports vs CustomPriceSheet vs PublicPriceSheet | + +## Discussion / Scratch space + +### Attribute scope + +#### Consistency regardless of who controls the String value + +* Provider-controlled columns: Initial discussion revolved around consistent casing for provider-specified String values. +* End-user-controlled columns: Recognized the need to establish consistency-related requirements for end-user-controlled String columns. +* FOCUS-controlled columns: Noted that these requirements also apply to FOCUS-controlled String value-capturing columns. + +#### String columns and Value format options + +* Current Value format options for String columns are: + * `currency code format`, + * `unit format`, + * `allowed values`, + * and `not specified`. + +* **Addressing String columns with `Value format`: `not specified` is our primary goal**, given the other Value formats already address consistency concerns. + +### Attribute name alternatives and reference to the attribute + +* Name alternatives: + * String Format + * String Handling **<-- selected by the group** + * String Consistency Handling + * Other suggestions? + +* How should we reference the attribute? + * Explicitly within individual column specs (in normative paragraph and constraint table, similar to e.g. Unit and Value)? + * Implicitly applicable to all String columns without explicitly referencing it in individual column specs (similar to null-handing)? **<-- selected by the group** + +* To avoid unintentionally suggesting a higher priority for these specific columns, current references to value-format consistency requirements were removed from the following columns: + * RegionId + * RegionName + * ResourceType + * CommitmentDiscountType + +### Requirements and Exceptions + +#### Requirements and Exceptions - v1.3 + +* Requirements: + * String values MUST maintain the original casing, spacing, and other relevant consistency factors as specified by providers and/or end-users. + * Changes to mutable string values (e.g., resource names) MUST be accurately reflected in charges related to subsequent costs incurred after the string value change and MUST NOT alter the original values in historical records, preserving data integrity and auditability for past billing periods. + * Immutable string values that refer to the same entity (e.g., resource identifiers) MUST remain consistent and unchanged across all billing periods. + +* Exceptions: + * None + +#### Requirements and Exceptions - v1.2 + +* Requirements: + * **String values appearing in the billing data MUST maintain the original casing, spacing, and other pertinent consistency factors.** + * **String values referring to the same entity SHOULD be consistent within a provider's context.** + * FOCUS scope is limited to billing data therefor SHOULD opposed to MUST + * **The provider SHOULD ensure that both provider-defined and user-input String values do not contain multiple consecutive spaces or leading/trailing spaces.** + * Include in the spec or only mention in the supporting content? + * **String-formatted columns MUST also adhere to null handling requirements.** + * Should null handling requirements be limited to provider-defined String values? For instance, is it ok to impose null if a provider didn't ensure the prevention of empty Strings at input? + +* Exceptions: + * None + +#### Requirements and Exceptions - v1.1 + +* Requirements: + * String values that refer to the same entity MUST be consistent (e.g., casing and spacing) within the context of the provider. + * String values MUST be provided with the original casing. + * Multiple consecutive spaces within a String MUST be reduced to a single space. + * String values MUST NOT contain leading or trailing spaces. + * String-formatted columns MUST also adhere to null handling requirements. + +* Exceptions: + * User-controlled columns MAY contain multiple consecutive spaces and/or leading or trailing spaces. From 78315ecc1917b4ab28a6e81d590dab7d56dae6df Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Mon, 22 Apr 2024 17:49:22 -0700 Subject: [PATCH 39/65] FOCUS #365: Updated the changelog with all changes (#381) Resolves #365 --------- Co-authored-by: Joaquin Co-authored-by: Alex Hullah --- CHANGELOG.md | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb..647fdf103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,204 @@ +# FinOps Open Cost and Usage Specification Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +**Added:** + +- `String handling` attribute +- `ChargeClass` column +- `ContractedCost` column +- `ContractedUnitPrice` column +- `RegionId` column +- `RegionName` column + +**Changed:** + +- `Column naming convention` attribute includes the following new provisions: + - Column IDs should not exceed 50 characters. +- `ChargeCategory` column updates: + - Added "Credit" value for credits and any applicable credit corrections. See added `ChargeClass` column. + - Updated "Usage", "Purchase", and "Tax" to include refunds/corrections. See added `ChargeClass` column. + - Updated "Adjustment" value to exclude credits and refunds. +- `ChargeFrequency` column updates: + - Column is recommended and may not be present. +- `CommitmentDiscountCategory` column updates: + - Column is conditional and only required when the provider supports commitment discounts. +- `CommitmentDiscountId` column updates: + - Column is conditional and only required when the provider supports commitment discounts. +- `CommitmentDiscountName` column updates: + - Column is conditional and only required when the provider supports commitment discounts. +- `CommitmentDiscountType` column updates: + - Column is conditional and only required when the provider supports commitment discounts. +- `EffectiveCost` column updates: + - Clarified that effective cost does not mix or "blend" costs across multiple charges. +- `ListUnitPrice` column updates: + - Column is conditional and only required when the provider publishes a price list that excludes discounts. +- `PricingCategory` column updates: + - Column is conditional and only required when the provider supports more than one pricing category value. +- `ResourceId` column updates: + - Column is conditional and only required when the provider supports billing based on provisioned resource instances. +- `ResourceName` column updates: + - Column is conditional and only required when the provider supports billing based on provisioned resource instances. +- `ResourceType` column updates: + - Column is conditional and only required when the provider supports billing based on provisioned resource instances and supports multiple "types" of resources. +- `SkuId` column updates: + - Column is conditional and only required when the provider publishes a SKU list. +- `SkuPriceId` column updates: + - Column is conditional and only required when the provider publishes a SKU price list. + - Must not be null when `ChargeClass` is "Regular" + - Must not be null when `ChargeCategory` is "Credit" or "Adjustment" and the charge is associated with a specific `SkuPriceId`. +- `SubAccountId` column updates: + - Column is conditional and only required when the provider supports a sub account construct. +- `SubAccountName` column updates: + - Column is conditional and only required when the provider supports a sub account construct. +- `Tags` column updates: + - Tag keys that cannot have a value must use a boolean `true` as the tag value. + - Column is conditional and only required when the provider supports setting user- or provider-defined tags. +- `UsageQuantity` column updates: + - Column is conditional and only required when the provider supports the measurement of usage. +- `UsageUnit` column updates: + - Column is conditional and only required when the provider supports the measurement of usage. + +**Fixed:** + +- `CommitmentDiscountType` column constraints were updated to show the column as required to align with the normative text. + +**Removed:** + +- `ChargeSubcategory` column - See `ChargeCategory` and `ChargeClass` columns +- `Region` column - See `RegionId` and `RegionName` columns + +[All unreleased changes](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/compare/v1.0-preview-cr...working_draft) + +
+ +## v1.0-preview +Announced November 15, 2023 + +**Added:** + +- `Discount handling` attribute +- `Key/value format` attribute +- `Numeric format` attribute +- `Unit format` attribute +- `ChargeDescription` column +- `ChargeFrequency` column +- `ChargeSubcategory` column +- `CommitmentDiscountCategory` column +- `CommitmentDiscountId` column +- `CommitmentDiscountName` column +- `CommitmentDiscountType` column +- `ListCost` column +- `ListUnitPrice` column +- `PricingCategory` column +- `PricingQuantity` column +- `PricingUnit` column +- `ResourceType` column +- `SkuId` column +- `SkuPriceId` column +- `Tags` column +- `UsageQuantity` column +- `UsageUnit` column + +**Changed:** + +- `Column naming convention` attribute includes the following new provisions: + - Columns with a `Category` suffix must be normalized. + - External, custom columns can be added but must be prefixed by `x_`. + - FOCUS columns must be listed before custom columns in the dataset. + - Added "SKU" as an exception to the "no acronyms" rule. The display name is "SKU" and column ID is `Sku`. +- `AmortizedCost` column renamed to `EffectiveCost` +- `ChargeType` column renamed to `ChargeCategory` + +[All 1.0-preview changes](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/compare/v0.5-cr...v1.0-preview-cr) + +
+ +## v0.5 +Announced June 24, 2023 + +**Added:** +- `Column naming convention` attribute +- `Currency code format` attribute +- `Date/time format` attribute +- `Null handling` attribute +- `AmortizedCost` column +- `AvailabilityZone` column +- `BilledCost` column +- `BillingAccountId` column +- `BillingAccountName` column +- `BillingCurrency` column +- `BillingPeriodEnd` column +- `BillingPeriodStart` column +- `ChargePeriodEnd` column +- `ChargePeriodStart` column +- `ChargeType` column +- `InvoiceIssuerName` column +- `ProviderName` column +- `PublisherName` column +- `Region` column +- `ResourceId` column +- `ResourceName` column +- `ServiceCategory` column +- `ServiceName` column +- `SubAccountId` column +- `SubAccountName` column + +[All 0.5 changes](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/compare/7106bbe...v0.5-cr) + +
+ +## Columns History + +This table maps the evolution of the billing data, showcasing column introductions and updates from its initial version 0.5 to the comprehensive revisions in "1.0-preview", "1.0" and beyond. + +| **Column ID** | **Revision Introduced** | **Latest Update** | +|------------------------------|-------------------------|-------------------| +| AvailabilityZone | 0.5 | | +| BilledCost | 0.5 | | +| BillingAccountId | 0.5 | | +| BillingAccountName | 0.5 | | +| BillingCurrency | 0.5 | | +| BillingPeriodEnd | 0.5 | | +| BillingPeriodStart | 0.5 | | +| ChargeCategory | 0.5 | 1.0 | +| ChargeClass | 1.0 | | +| ChargeDescription | 1.0-preview | | +| ChargeFrequency | 1.0-preview | | +| ChargePeriodEnd | 0.5 | | +| ChargePeriodStart | 0.5 | | +| ChargeSubcategory | 1.0-preview | Removed in 1.0 | +| CommitmentDiscountCategory | 1.0-preview | | +| CommitmentDiscountId | 1.0-preview | | +| CommitmentDiscountName | 1.0-preview | | +| CommitmentDiscountType | 1.0-preview | | +| ContractedCost | 1.0 | | +| ContractedUnitPrice | 1.0 | | +| EffectiveCost | 0.5 | | +| InvoiceIssuerName | 0.5 | | +| ListCost | 1.0-preview | | +| ListUnitPrice | 1.0-preview | | +| PricingCategory | 1.0-preview | | +| PricingQuantity | 1.0-preview | | +| PricingUnit | 1.0-preview | | +| ProviderName | 0.5 | | +| PublisherName | 0.5 | | +| Region | 0.5 | Removed in 1.0 | +| RegionId | 1.0 | | +| RegionName | 1.0 | | +| ResourceId | 0.5 | | +| ResourceName | 0.5 | | +| ResourceType | 1.0-preview | | +| ServiceCategory | 0.5 | | +| ServiceName | 0.5 | | +| SkuId | 1.0-preview | | +| SkuPriceId | 1.0-preview | 1.0 | +| SubAccountId | 0.5 | | +| SubAccountName | 0.5 | | +| Tags | 1.0-preview | 1.0 | +| UsageQuantity | 1.0-preview | | +| UsageUnit | 1.0-preview | | From 6a527f64b07f4b384f14bea1e8ef139c9e7bf3c5 Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Mon, 22 Apr 2024 18:24:34 -0700 Subject: [PATCH 40/65] FOCUS #330: Pricing Category value updates (#383) Updates PricingCategory values: - "On-Demand" to "Standard" - "Commitment-Based" to "Committed" Related to #330 --- CHANGELOG.md | 6 +- specification/columns/pricingcategory.md | 16 +-- specification/glossary.md | 2 +- supporting_content/columns/chargecategory.md | 18 +-- supporting_content/columns/pricingcategory.md | 113 +++++++++--------- 5 files changed, 79 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 647fdf103..b5d96e879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Column is conditional and only required when the provider publishes a price list that excludes discounts. - `PricingCategory` column updates: - Column is conditional and only required when the provider supports more than one pricing category value. + - Changed "On-Demand" to "Standard". + - Changed "Commitment-Based" to "Committed". - `ResourceId` column updates: - Column is conditional and only required when the provider supports billing based on provisioned resource instances. - `ResourceName` column updates: @@ -56,8 +58,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `SubAccountName` column updates: - Column is conditional and only required when the provider supports a sub account construct. - `Tags` column updates: - - Tag keys that cannot have a value must use a boolean `true` as the tag value. - Column is conditional and only required when the provider supports setting user- or provider-defined tags. + - Tag keys that cannot have a value must use a boolean `true` as the tag value. - `UsageQuantity` column updates: - Column is conditional and only required when the provider supports the measurement of usage. - `UsageUnit` column updates: @@ -182,7 +184,7 @@ This table maps the evolution of the billing data, showcasing column introductio | InvoiceIssuerName | 0.5 | | | ListCost | 1.0-preview | | | ListUnitPrice | 1.0-preview | | -| PricingCategory | 1.0-preview | | +| PricingCategory | 1.0-preview | 1.0 | | PricingQuantity | 1.0-preview | | | PricingUnit | 1.0-preview | | | ProviderName | 0.5 | | diff --git a/specification/columns/pricingcategory.md b/specification/columns/pricingcategory.md index f119ea223..de8e1f991 100644 --- a/specification/columns/pricingcategory.md +++ b/specification/columns/pricingcategory.md @@ -7,8 +7,8 @@ The PricingCategory column adheres to the following requirements: * PricingCategory MUST be present in the billing data when the provider supports more than one pricing category across all SKUs and MUST be of type String. * PricingCategory MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MUST be null for other ChargeCategory values. * PricingCategory MUST be one of the allowed values. -* PricingCategory MUST be "On-Demand" when pricing is predetermined at the standard rate for the [billing account](#glossary:billing-account). -* PricingCategory MUST be "Commitment-Based" when [CommitmentDiscountId](#commitmentdiscountid) is not null. +* PricingCategory MUST be "Standard" when pricing is predetermined at the agreed upon rate for the [billing account](#glossary:billing-account). +* PricingCategory MUST be "Committed" when [CommitmentDiscountId](#commitmentdiscountid) is not null. * PricingCategory MUST be "Dynamic" when pricing is determined by the provider and may change over time, regardless of predetermined agreement pricing. * PricingCategory MUST be "Other" when there is a pricing model but none of the allowed values apply. @@ -36,12 +36,12 @@ Describes the pricing model used for a charge at the time of use or purchase. Allowed values: -| Value | Description | -| :--------------- | :-------------------------------| -| On-Demand | Charges priced at the standard rate for the billing account. This includes any flat rate and volume/tiered pricing but does not include dynamic or commitment-based discount pricing. | -| Dynamic | Charges priced at a variable rate determined by the provider. This includes any product or service with a unit price the provider can change without notice, like interruptible or low priority resources. | -| Commitment-Based | Charges with reduced prices due to a commitment-based discount specified by the Commitment Discount ID. | -| Other | Charges priced in a way not covered by another pricing category. | +| Value | Description | +| :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Standard | Charges priced at the agreed upon rate for the billing account, including negotiated discounts. This includes any flat rate and volume/tiered pricing but does not include dynamic or commitment-based discount pricing. | +| Dynamic | Charges priced at a variable rate determined by the provider. This includes any product or service with a unit price the provider can change without notice, like interruptible or low priority resources. | +| Committed | Charges with reduced prices due to a commitment-based discount specified by the Commitment Discount ID. | +| Other | Charges priced in a way not covered by another pricing category. | ## Introduced (version) diff --git a/specification/glossary.md b/specification/glossary.md index d05208feb..1724c7a0e 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -94,7 +94,7 @@ A company or organization that provides outsourced management and support of a r On-Demand -A term that describes a service that is available and provided immediately or as needed, without requiring a pre-scheduled appointment or prior arrangement. In Cloud Computing, virtual machines can be created and terminated as needed, i.e. on demand. +A term that describes a service that is available and provided immediately or as needed, without requiring a pre-scheduled appointment or prior arrangement. In cloud computing, virtual machines can be created and terminated as needed, i.e. on demand. Practitioner diff --git a/supporting_content/columns/chargecategory.md b/supporting_content/columns/chargecategory.md index 073eada22..1ac7c7889 100644 --- a/supporting_content/columns/chargecategory.md +++ b/supporting_content/columns/chargecategory.md @@ -149,12 +149,12 @@ Permutations: ### Examples of how Charge Type relates to Pricing Category / Charge Frequency columns -| Scenario| ChargeCategory | ChargeSubcategory | PricingCategory | Charge Frequency | -|-|-|-|-|-| -| Upfront discount purchase | Purchase| NULL | On-Demand | One-time | -| Partial Upfront discount monthly fee | Purchase | NULL | On-Demand | Recurring | -| Usage covered by upfront portion of partial upfront discount | Usage | Used Commitment | Commitment-based | Usage-based | -| Unused commitment of partial upfront discount | Usage | Unused Commitment | Commitment-based | Usage-based | -| Usage not covered by discount | Usage | On-Demand | On-Demand | Usage-based| -| Refund | Adjustment | Refund | NULL | One-time | -| Usage invoice tax charge | Tax | NULL | NULL | Recurring | +| Scenario | ChargeCategory | ChargeSubcategory | PricingCategory | Charge Frequency | +| ------------------------------------------------------------ | -------------- | ----------------- | --------------- | ---------------- | +| Upfront discount purchase | Purchase | NULL | Standard | One-time | +| Partial Upfront discount monthly fee | Purchase | NULL | Standard | Recurring | +| Usage covered by upfront portion of partial upfront discount | Usage | Used Commitment | Committed | Usage-based | +| Unused commitment of partial upfront discount | Usage | Unused Commitment | Committed | Usage-based | +| Usage not covered by discount | Usage | On-Demand | Standard | Usage-based | +| Refund | Adjustment | Refund | NULL | One-time | +| Usage invoice tax charge | Tax | NULL | NULL | Recurring | diff --git a/supporting_content/columns/pricingcategory.md b/supporting_content/columns/pricingcategory.md index 0544c9788..d899a6e07 100644 --- a/supporting_content/columns/pricingcategory.md +++ b/supporting_content/columns/pricingcategory.md @@ -14,68 +14,69 @@ Current column mappings found in available data sets: Current values observed in billing data for various scenarios: -| Provider | Data set | Provider value | PricingCategory | PricingSubcategory | -| --------- | --------------------------- | ------------------ | ---------------- | ------------------ | -| AWS | CUR (PurchaseOption) | On-Demand | On-Demand | (depends on usage) | -| AWS | CUR (PurchaseOption) | Reserved Instances | Commitment-Based | Committed Usage | -| AWS | CUR (PurchaseOption) | Spot Instances | Dynamic | Spot | -| AWS | CUR (PurchaseOption) | Dedicated Hosts | On-Demand | (depends on usage) | -| Microsoft | Cost Details (PricingModel) | OnDemand | On-Demand | -| Microsoft | Cost Details (PricingModel) | SavingsPlan | Commitment-Based | Committed Spend | -| Microsoft | Cost Details (PricingModel) | Reservation | Commitment-Based | Committed Usage | -| Microsoft | Cost Details (PricingModel) | Spot | Reservation | +| Provider | Data set | Provider value | PricingCategory | PricingSubcategory | +| --------- | --------------------------- | ------------------ | --------------- | ------------------ | +| AWS | CUR (PurchaseOption) | On-Demand | Standard | (depends on usage) | +| AWS | CUR (PurchaseOption) | Reserved Instances | Committed | Committed Usage | +| AWS | CUR (PurchaseOption) | Spot Instances | Dynamic | Spot | +| AWS | CUR (PurchaseOption) | Dedicated Hosts | Standard | (depends on usage) | +| Microsoft | Cost Details (PricingModel) | OnDemand | Standard | | +| Microsoft | Cost Details (PricingModel) | SavingsPlan | Committed | Committed Spend | +| Microsoft | Cost Details (PricingModel) | Reservation | Committed | Committed Usage | +| Microsoft | Cost Details (PricingModel) | Spot | Reservation | | ## Documentation -- AWS: https://docs.aws.amazon.com/cur/latest/userguide/product-columns.html -- GCP -- Microsoft: https://learn.microsoft.com/azure/cost-management-billing/automate/understand-usage-details-fields +* AWS: https://docs.aws.amazon.com/cur/latest/userguide/product-columns.html +* GCP +* Microsoft: https://learn.microsoft.com/azure/cost-management-billing/automate/understand-usage-details-fields ## Discussion Topics -- Goal of the column is to enable practitioners to identify charges that have reduced prices vs. not. - - The most common question for this column is to identify commitment-based discounts and spot separate from on-demand. -- In 0.5, we didn't have enough time to close on how spot would be included: - - Someone mentioned that "spot" was a marketing term, so we tried to avoid it. - - We discussed values like "Preemptible" (confusing), "Interruptible" (not a pricing model), "Market-Based", "Variable", and "Dynamic". Ultimately, we agreed on "Dynamic". - - Then we questioned whether it "Dynamic" would be clear enough to practitioners who are looking for spot usage. -- In 1.0: - - We brought PricingModel back into discussion and had the same issues with "spot" being clearly understood as "Dynamic" so we decided to focus on other columns first. - - Over time, we got several requests to add a "PricingModel" column (that name explicitly), so we brought it back into discussion again. - - We agreed to add PricingModel as-is (with spot showing as "Dynamic"). -- While in PR, one member shared a link to IBM's documentation about how you're charged: https://cloud.ibm.com/docs/billing-usage?topic=billing-usage-charges - - IBM talks about Fixed, Metered, Tiered, and Reserved values. - - We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. - - The main concern about bringing these values in is that to get the on-demand costs, you'd have to look at 2 values, which makes it more complicated for practitioners. -- There was a poll with all members to determine if we should merge "Fixed" and "On-Demand" pricing options since they sounded near identical. - - 8 preferred merging and 3 preferred keeping them separate, so we decided to merge them. - - This was also discussed in the weekly member meeting, where people questioned using "On-Demand" for things that don't have a "pricing" model. - - We decided to use null when there is no price (SkuPriceId is null). - - As a note, multiple people have commented on nulls being more difficult for data analysis (since there's no clear meaning to why it's null). We did not have time to discuss this in the meeting, but it's something we should discuss in the future as it applies to all columns. - - The group also asked to add an "Other" option to account for any new pricing model that may come up in the future. -- Later, while still in PR, there was a concern about "dynamic on-demand pricing": - - This brought the IBM values of Fixed, Metered, Tiered, and Reserved back into the discussion as those were a more detailed version of what we were trying to do. - - We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. - - A few weeks before this, we as a group decided to use the term "Category" for normalized types and we also introduced a ChargeSubcategory column as the next level grouping. - - Based on this Category/Subcategory pattern, we decided to break PricingModel into PricingCategory and PricingSubcategory, adding a more detailed breakdown of each category. - - Regarding "dynamic on-demand", this isn't possible given our current definitions (always-changing price vs. predetermined set price). - - As part of these discussions, we also discussed whether "On-Demand" was the right term. - - We discussed "Standard" as a replacement, but agreed "On-Demand" is more common and clear for the pricing model of pricing that is based on the published price for the billing account. (Note: Tiered pricing (aka volume-based discounts) are also predetermined and published, so they are also "On-Demand" by our definition.) - - We felt "Standard" was more clear as a differentiator from "Tiered" pricing. Another alternative was "Flat Rate". - - We also discussed whether to use "Commitment-Based" or "Discounted". - - If we use "Discounted", then any future discounting strategy could get rolled into a single column without the need to change values. - - The main downside of this is that, given how important commitment-based discounts are (and the fact that they are one of the primary reasons for adding this column), we felt it was important to call them out explicitly. - - Additionally, given different discount strategies will price things differently, it's also important that we distinguish the separate pricing models at the top level. - - We also didn't have any other clear examples that would fall into "Discounted" pricing that would be meaningfully grouped together in a way that practitioners would want to see together and not distinguished separately from their committed costs. - - We also discussed the term "Dynamic" and whether it was clear enough. - - During this, we discovered that "spot" is not a marketing term and is in fact a pricing construct for an always-changing price that a good or service can be immediately sold at. - - We discussed replacing "Dynamic" with "Spot", but agreed that "Dynamic" is more inclusive of other types of dynamic pricing models that may be introduced in the future and would likely be desirable to be grouped together. - - Given we cannot predict all pricing models that will be introduced in the future, we decided to also add "Other" in each subcategory. -- Unfortunately, we didn't think we had enough time to close PricingSubcategory, so we decided to hold that for after 1.0. +* Goal of the column is to enable practitioners to identify charges that have reduced prices vs. not. + * The most common question for this column is to identify commitment-based discounts and spot separate from on-demand. +* In 0.5, we didn't have enough time to close on how spot would be included: + * Someone mentioned that "spot" was a marketing term, so we tried to avoid it. + * We discussed values like "Preemptible" (confusing), "Interruptible" (not a pricing model), "Market-Based", "Variable", and "Dynamic". Ultimately, we agreed on "Dynamic". + * Then we questioned whether it "Dynamic" would be clear enough to practitioners who are looking for spot usage. +* In 1.0: + * We brought PricingModel back into discussion and had the same issues with "spot" being clearly understood as "Dynamic" so we decided to focus on other columns first. + * Over time, we got several requests to add a "PricingModel" column (that name explicitly), so we brought it back into discussion again. + * We agreed to add PricingModel as-is (with spot showing as "Dynamic"). +* While in PR, one member shared a link to IBM's documentation about how you're charged: https://cloud.ibm.com/docs/billing-usage?topic=billing-usage-charges + * IBM talks about Fixed, Metered, Tiered, and Reserved values. + * We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. + * The main concern about bringing these values in is that to get the on-demand costs, you'd have to look at 2 values, which makes it more complicated for practitioners. +* There was a poll with all members to determine if we should merge "Fixed" and "On-Demand" pricing options since they sounded near identical. + * 8 preferred merging and 3 preferred keeping them separate, so we decided to merge them. + * This was also discussed in the weekly member meeting, where people questioned using "On-Demand" for things that don't have a "pricing" model. + * We decided to use null when there is no price (SkuPriceId is null). + * As a note, multiple people have commented on nulls being more difficult for data analysis (since there's no clear meaning to why it's null). We did not have time to discuss this in the meeting, but it's something we should discuss in the future as it applies to all columns. + * The group also asked to add an "Other" option to account for any new pricing model that may come up in the future. +* Later, while still in PR, there was a concern about "dynamic on-demand pricing": + * This brought the IBM values of Fixed, Metered, Tiered, and Reserved back into the discussion as those were a more detailed version of what we were trying to do. + * We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. + * A few weeks before this, we as a group decided to use the term "Category" for normalized types and we also introduced a ChargeSubcategory column as the next level grouping. + * Based on this Category/Subcategory pattern, we decided to break PricingModel into PricingCategory and PricingSubcategory, adding a more detailed breakdown of each category. + * Regarding "dynamic on-demand", this isn't possible given our current definitions (always-changing price vs. predetermined set price). + * As part of these discussions, we also discussed whether "On-Demand" was the right term. + * We discussed "Standard" as a replacement, but agreed "On-Demand" is more common and clear for the pricing model of pricing that is based on the published price for the billing account. (Note: Tiered pricing (aka volume-based discounts) are also predetermined and published, so they are also "On-Demand" by our definition.) + * We felt "Standard" was more clear as a differentiator from "Tiered" pricing. Another alternative was "Flat Rate". + * We also discussed whether to use "Commitment-Based" or "Discounted". + * If we use "Discounted", then any future discounting strategy could get rolled into a single column without the need to change values. + * The main downside of this is that, given how important commitment-based discounts are (and the fact that they are one of the primary reasons for adding this column), we felt it was important to call them out explicitly. + * Additionally, given different discount strategies will price things differently, it's also important that we distinguish the separate pricing models at the top level. + * We also didn't have any other clear examples that would fall into "Discounted" pricing that would be meaningfully grouped together in a way that practitioners would want to see together and not distinguished separately from their committed costs. + * We also discussed the term "Dynamic" and whether it was clear enough. + * During this, we discovered that "spot" is not a marketing term and is in fact a pricing construct for an always-changing price that a good or service can be immediately sold at. + * We discussed replacing "Dynamic" with "Spot", but agreed that "Dynamic" is more inclusive of other types of dynamic pricing models that may be introduced in the future and would likely be desirable to be grouped together. + * Given we cannot predict all pricing models that will be introduced in the future, we decided to also add "Other" in each subcategory. +* Unfortunately, we didn't think we had enough time to close PricingSubcategory, so we decided to hold that for after 1.0. +* On April 3, 2024, we agreed to change "On-Demand" to "Standard" and "Commitment-Based" to "Committed". Open issues: -- Issues with null values (e.g., usability, dimensional modeling). -- Define PricingSubcategory column. -- Define principles to support PricingCategory values (similar to ServiceCategory). -- Consider defining an attribute that applies to all Category/Subcategory columns (e.g., must have principles, "Other" value). +* Issues with null values (e.g., usability, dimensional modeling). +* Define PricingSubcategory column. +* Define principles to support PricingCategory values (similar to ServiceCategory). +* Consider defining an attribute that applies to all Category/Subcategory columns (e.g., must have principles, "Other" value). From c763cddc873afb5bdd810f5d447787122fd1f452 Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Tue, 23 Apr 2024 14:45:45 -0700 Subject: [PATCH 41/65] FOCUS #330: CommitmentDiscountStatus column (#382) Related to #330 --- CHANGELOG.md | 2 + specification/attributes/discount_handling.md | 7 ++-- specification/columns/columns.mdpp | 1 + .../columns/commitmentdiscountstatus.md | 38 +++++++++++++++++++ specification/use_case_library.md | 2 +- supporting_content/columns/chargecategory.md | 20 +++++----- .../columns/commitmentdiscountusage.md | 18 +++++++++ 7 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 specification/columns/commitmentdiscountstatus.md create mode 100644 supporting_content/columns/commitmentdiscountusage.md diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d96e879..8b889bbb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `String handling` attribute - `ChargeClass` column +- `CommitmentDiscountStatus` column - `ContractedCost` column - `ContractedUnitPrice` column - `RegionId` column @@ -177,6 +178,7 @@ This table maps the evolution of the billing data, showcasing column introductio | CommitmentDiscountCategory | 1.0-preview | | | CommitmentDiscountId | 1.0-preview | | | CommitmentDiscountName | 1.0-preview | | +| CommitmentDiscountStatus | 1.0 | | | CommitmentDiscountType | 1.0-preview | | | ContractedCost | 1.0 | | | ContractedUnitPrice | 1.0 | | diff --git a/specification/attributes/discount_handling.md b/specification/attributes/discount_handling.md index df3c99ab7..b4446115f 100644 --- a/specification/attributes/discount_handling.md +++ b/specification/attributes/discount_handling.md @@ -31,13 +31,12 @@ Indicates how to include and apply discounts to usage charges or rows. * Each discount MUST be identifiable using existing FOCUS columns. * Rows with a commitment-based discount applied to them MUST include a CommitmentDiscountId. * If a provider applies a discount that cannot be represented by a FOCUS column, they SHOULD include additional columns to identify the source of the discount. -* ChargeSubCategory MUST NOT be null for rows where ChargeType is "Usage" and the row received reduced rates from a discount. * Purchased discounts (e.g., commitment-based discounts) MUST be amortized. * The BilledCost MUST be 0 for any row where the commitment covers the entire cost for the charge period. * The EffectiveCost MUST include the portion of the amortized purchase cost that applies to this row. - * ChargeSubcategory MUST be "Used Commitment" for rows that received a reduced price from that commitment. - * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. ChargeSubcategory MUST be "Unused Commitment". - * The sum of the EffectiveCost for all "Used Commitment" and "Unused Commitment" rows for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. + * CommitmentDiscountStatus MUST be "Used" for rows that received a reduced price from that commitment. + * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. CommitmentDiscountStatus MUST be "Unused". + * The sum of the EffectiveCost for all rows where CommitmentDiscountStatus is "Used" or "Unused" for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. * Credits that are applied after the fact MUST use a ChargeType of "Adjustment" and ChargeSubcategory of "Credit". ## Exceptions diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index 57af24748..cbc5835a7 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -20,6 +20,7 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "commitmentdiscountid.md",1 !INCLUDE "commitmentdiscountname.md",1 !INCLUDE "commitmentdiscounttype.md",1 +!INCLUDE "commitmentdiscountstatus.md",1 !INCLUDE "contractedcost.md",1 !INCLUDE "contractedunitprice.md",1 !INCLUDE "effectivecost.md",1 diff --git a/specification/columns/commitmentdiscountstatus.md b/specification/columns/commitmentdiscountstatus.md new file mode 100644 index 000000000..a0d58bf4b --- /dev/null +++ b/specification/columns/commitmentdiscountstatus.md @@ -0,0 +1,38 @@ +# Commitment Discount Status + +Commitment Discount Status indicates whether the charge corresponds with the consumption of the [*commitment-based discount*](#glossary:commitment-based-discount) identified in the CommitmentDiscountId column or the unused portion of the committed amount. + +The CommitmentDiscountStatus column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. The CommitmentDiscountCategory MUST be one of the allowed values. + +## Column ID + +CommitmentDiscountStatus + +## Display name + +Commitment Discount Status + +## Description + +Indicates whether the charge corresponds with the consumption of a *commitment-based discount* or the unused portion of the committed amount. + +## Content constraints + +| Constraint | Value | +| :-------------- | :------------- | +| Column type | Dimension | +| Feature level | Conditional | +| Allows nulls | True | +| Data type | String | +| Value format | Allowed Values | + +Allowed values: + +| Value | Description | +| :----- | :-------------------------------------------------------------------------- | +| Used | Charges that utilized a specific amount of a commitment-based discount. | +| Unused | Charges that represent the unused portion of the commitment-based discount. | + +## Introduced (version) + +1.0 diff --git a/specification/use_case_library.md b/specification/use_case_library.md index 307e966a6..0d1731d57 100644 --- a/specification/use_case_library.md +++ b/specification/use_case_library.md @@ -36,7 +36,7 @@ The following table contains a set of commonly performed FinOps scenarios that w | FinOps Practitioner | Managing Anomalies | As a FinOps Practitioner, I need to see the daily costs across all cloud providers, billing accounts, sub accounts, and region | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
EffectiveCost
Provider
Region | | FinOps Practitioner | Managing Anomalies | As a FinOps practitioner, I need to see the daily costs across all cloud providers, billing accounts, sub accounts, and service | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
EffectiveCost
Provider
ServiceName | | FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track all commitment based discounts purchased for a time period | Provider
BillingAccountID
CommitmentDiscountId
CommitmentDiscountType
BilledCost
ChargePeriodStart
ChargeCategory | -| FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track unused commitment charges in any given time period so that I consider them in my future commitment planning or remedy them | ChargeSubcategory (filter)
CommitmentDiscountID
BilledCost
ChargePeriodStart | +| FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track unused commitment charges in any given time period so that I consider them in my future commitment planning or remedy them | CommitmentDiscountStatus (filter)
CommitmentDiscountID
BilledCost
ChargePeriodStart | | FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture. | ChargeType
ChargeDescription
ChargePeriodStart
Provider
ResourceType
SubAccountID
ServiceName | | FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture within a specific service | ChargeType
ChargeDescription
ChargePeriodStart
Provider
ResourceType
SubAccountID
ServiceName | | FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, identify total refunds within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeSubcategory | diff --git a/supporting_content/columns/chargecategory.md b/supporting_content/columns/chargecategory.md index 1ac7c7889..c4047d6d2 100644 --- a/supporting_content/columns/chargecategory.md +++ b/supporting_content/columns/chargecategory.md @@ -8,7 +8,7 @@ Current column mappings found in available data sets: | --------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AWS | CUR | `bill/BillType` (Anniversary, Purchase, Refund)
`lineItem/LineItemType` (Usage, Tax, BundledDiscount, Credit, Discount, DiscountedUsage, Fee, Refund, RIFee, SavingsPlanUpfrontFee, SavingsPlanRecurringFee, SavingsPlanCoveredUsage, SavingsPlanNegation) | | GCP | BigQuery Billing Export | `Cost type` (regular, tax, adjustment, or rounding error) | -| Microsoft | Cost details | `ChargeCategory` (Purchase, Usage, Refund, Adjustment, Tax?)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) | +| Microsoft | Cost details | `ChargeType` (Purchase, Usage, Refund, Adjustment, Tax?)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) | ## Example usage scenarios @@ -149,12 +149,12 @@ Permutations: ### Examples of how Charge Type relates to Pricing Category / Charge Frequency columns -| Scenario | ChargeCategory | ChargeSubcategory | PricingCategory | Charge Frequency | -| ------------------------------------------------------------ | -------------- | ----------------- | --------------- | ---------------- | -| Upfront discount purchase | Purchase | NULL | Standard | One-time | -| Partial Upfront discount monthly fee | Purchase | NULL | Standard | Recurring | -| Usage covered by upfront portion of partial upfront discount | Usage | Used Commitment | Committed | Usage-based | -| Unused commitment of partial upfront discount | Usage | Unused Commitment | Committed | Usage-based | -| Usage not covered by discount | Usage | On-Demand | Standard | Usage-based | -| Refund | Adjustment | Refund | NULL | One-time | -| Usage invoice tax charge | Tax | NULL | NULL | Recurring | +| Scenario | ChargeCategory | ChargeSubcategory | PricingCategory | ChargeFrequency | CommitmentDisocuntUsage | +| ------------------------------------------------------------ | -------------- | ----------------- | --------------- | --------------- | ----------------------- | +| Upfront discount purchase | Purchase | NULL | Standard | One-time | NULL | +| Partial Upfront discount monthly fee | Purchase | NULL | Standard | Recurring | NULL | +| Usage covered by upfront portion of partial upfront discount | Usage | NULL | Committed | Usage-based | Unused | +| Unused commitment of partial upfront discount | Usage | NULL | Committed | Usage-based | Used | +| Usage not covered by discount | Usage | On-Demand | Standard | Usage-based | NULL | +| Refund | Adjustment | Refund | NULL | One-time | NULL | +| Usage invoice tax charge | Tax | NULL | NULL | Recurring | NULL | diff --git a/supporting_content/columns/commitmentdiscountusage.md b/supporting_content/columns/commitmentdiscountusage.md new file mode 100644 index 000000000..b8306232f --- /dev/null +++ b/supporting_content/columns/commitmentdiscountusage.md @@ -0,0 +1,18 @@ +# Column: CommitmentDiscountUsage + +## Example provider mappings + +Current column mappings found in available data sets: + +| Provider | Data set | Column | +| --------- | ----------------------- | ---------------------------------------------------------------------- | +| AWS | CUR | `lineItem/LineItemType` (SavingsPlanCoveredUsage, SavingsPlanNegation) | +| GCP | BigQuery Billing Export | None | +| Microsoft | Cost details | `ChargeType` (Usage, UnusedReservation, UnusedSavingsPlan) | + +## Discussion / Scratch space + +- Moved from ChargeSubcategory that was defined in 1.0-preview. +- Alternative values discussed: + - Used, Usage, Consumption + - Unused, Not Used, Waste, Wastage From 8be348186800b6d9b6a26244f7769de030e98b2a Mon Sep 17 00:00:00 2001 From: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:21:10 -0700 Subject: [PATCH 42/65] Update naming and ordering attribute (#416) Update naming and ordering attribute to reference "ordering" explicitly in various places. This is a replacement pull request [for this request](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/pull/405) which was generated from a repo fork. This new PR was generated from a branch created directly in the FOCUS repo. --------- Co-authored-by: Udam Dewaraja --- CHANGELOG.md | 1 + specification/attributes/attributes.mdpp | 2 +- ...ntion.md => column_naming_and_ordering.md} | 21 +++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) rename specification/attributes/{column_naming_convention.md => column_naming_and_ordering.md} (71%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b889bbb6..cdebd3988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `Column naming convention` attribute includes the following new provisions: - Column IDs should not exceed 50 characters. + - Attribute renamed to `Column naming and ordering` to denote it also includes rules for column ordering. - `ChargeCategory` column updates: - Added "Credit" value for credits and any applicable credit corrections. See added `ChargeClass` column. - Updated "Usage", "Purchase", and "Tax" to include refunds/corrections. See added `ChargeClass` column. diff --git a/specification/attributes/attributes.mdpp b/specification/attributes/attributes.mdpp index a7a8508b7..240feac6a 100644 --- a/specification/attributes/attributes.mdpp +++ b/specification/attributes/attributes.mdpp @@ -5,7 +5,7 @@ conventions, data types, formatting standardizations, etc. Attributes may introd for data granularity, recency, frequency, etc. Requirements defined in attributes are necessary for servicing [FinOps capabilities][FODOFC] accurately using a standard set of instructions regardless of the origin of the data. -!INCLUDE "column_naming_convention.md",1 +!INCLUDE "column_naming_and_ordering.md",1 !INCLUDE "currency_code_format.md",1 !INCLUDE "datetime_format.md",1 !INCLUDE "discount_handling.md",1 diff --git a/specification/attributes/column_naming_convention.md b/specification/attributes/column_naming_and_ordering.md similarity index 71% rename from specification/attributes/column_naming_convention.md rename to specification/attributes/column_naming_and_ordering.md index ebfc83b6c..95a3b2ae6 100644 --- a/specification/attributes/column_naming_convention.md +++ b/specification/attributes/column_naming_and_ordering.md @@ -1,23 +1,24 @@ -# Column Naming Convention +# Column Naming and Ordering -Column IDs provided in cost data following a consistent naming convention reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. +Column IDs provided in cost data following a consistent naming and ordering convention reduce friction for FinOps practitioners who consume the data for analysis, reporting, and other use cases. -All columns defined in the FOCUS specification MUST follow the naming requirements listed below. +All columns defined in the FOCUS specification MUST follow the naming and ordering requirements listed below. ## Attribute ID -ColumnNamingConvention +ColumnNamingAndOrdering ## Attribute Name -Column Naming Convention +Column Naming and Ordering ## Description -Naming convention for columns appearing in billing data. +Naming and ordering convention for columns appearing in billing data. ## Requirements +### Column Names * All columns defined by FOCUS MUST follow the following rules: * Column IDs MUST use [Pascal case](https://techterms.com/definition/pascalcase). * Column IDs MUST NOT use abbreviations. @@ -28,10 +29,12 @@ Naming convention for columns appearing in billing data. * All custom columns MUST be prefixed with a consistent `x_` prefix to identify them as external, custom columns and distinguish them from FOCUS columns to avoid conflicts in future releases. * Columns that have an ID and a Name MUST have the `Id` or `Name` suffix in the Column ID. Display Name for a Column MAY avoid the `Name` suffix if it is considered superfluous. * Columns with the `Category` suffix MUST be normalized. -* Custom (e.g., provider-defined) columns SHOULD follow the same rules as FOCUS(*) columns listed above. +* Custom (e.g., provider-defined) columns SHOULD follow the same rules listed above for FOCUS columns. + +### Column Order * All FOCUS columns SHOULD be first in the provided dataset. - * Custom columns SHOULD be listed after all FOCUS columns and SHOULD NOT be intermixed. - * Columns MAY be sorted alphabetically but custom columns SHOULD be after all FOCUS columns. +* Custom columns SHOULD be listed after all FOCUS columns and SHOULD NOT be intermixed. +* Columns MAY be sorted alphabetically, but custom columns SHOULD be after all FOCUS columns. ## Exceptions From d3da5828321215fc0b380cad8046c1dd27fa1dfb Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Wed, 24 Apr 2024 16:03:48 -0700 Subject: [PATCH 43/65] FOCUS #330: Replace ChargeSubcategory references after ChargeClass inclusion (#402) Co-authored-by: Udam Dewaraja --- .../attributes/column_naming_and_ordering.md | 2 + specification/attributes/discount_handling.md | 8 +- specification/columns/chargesubcategory.md | 64 --------------- specification/columns/columns.mdpp | 1 - specification/columns/contractedcost.md | 2 +- specification/columns/effectivecost.md | 2 +- specification/columns/listcost.md | 2 +- specification/columns/pricingquantity.md | 2 +- specification/columns/usagequantity.md | 2 +- specification/use_case_library.md | 4 +- .../attributes/discount_handling.md | 4 +- supporting_content/columns/chargecategory.md | 20 ++--- .../columns/chargesubcategory.md | 39 --------- supporting_content/columns/pricingcategory.md | 80 +++++++++---------- 14 files changed, 65 insertions(+), 167 deletions(-) delete mode 100644 specification/columns/chargesubcategory.md delete mode 100644 supporting_content/columns/chargesubcategory.md diff --git a/specification/attributes/column_naming_and_ordering.md b/specification/attributes/column_naming_and_ordering.md index 95a3b2ae6..1ae74bac0 100644 --- a/specification/attributes/column_naming_and_ordering.md +++ b/specification/attributes/column_naming_and_ordering.md @@ -19,6 +19,7 @@ Naming and ordering convention for columns appearing in billing data. ## Requirements ### Column Names + * All columns defined by FOCUS MUST follow the following rules: * Column IDs MUST use [Pascal case](https://techterms.com/definition/pascalcase). * Column IDs MUST NOT use abbreviations. @@ -32,6 +33,7 @@ Naming and ordering convention for columns appearing in billing data. * Custom (e.g., provider-defined) columns SHOULD follow the same rules listed above for FOCUS columns. ### Column Order + * All FOCUS columns SHOULD be first in the provided dataset. * Custom columns SHOULD be listed after all FOCUS columns and SHOULD NOT be intermixed. * Columns MAY be sorted alphabetically, but custom columns SHOULD be after all FOCUS columns. diff --git a/specification/attributes/discount_handling.md b/specification/attributes/discount_handling.md index b4446115f..ec723fdfc 100644 --- a/specification/attributes/discount_handling.md +++ b/specification/attributes/discount_handling.md @@ -34,10 +34,10 @@ Indicates how to include and apply discounts to usage charges or rows. * Purchased discounts (e.g., commitment-based discounts) MUST be amortized. * The BilledCost MUST be 0 for any row where the commitment covers the entire cost for the charge period. * The EffectiveCost MUST include the portion of the amortized purchase cost that applies to this row. - * CommitmentDiscountStatus MUST be "Used" for rows that received a reduced price from that commitment. - * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. CommitmentDiscountStatus MUST be "Unused". - * The sum of the EffectiveCost for all rows where CommitmentDiscountStatus is "Used" or "Unused" for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. -* Credits that are applied after the fact MUST use a ChargeType of "Adjustment" and ChargeSubcategory of "Credit". + * ChargeSubcategory MUST be "Used Commitment" for rows that received a reduced price from that commitment. + * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. ChargeSubcategory MUST be "Unused Commitment". + * The sum of the EffectiveCost for all "Used Commitment" and "Unused Commitment" rows for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. +* Credits that are applied after the fact MUST use a ChargeCategory of "Credit". ## Exceptions diff --git a/specification/columns/chargesubcategory.md b/specification/columns/chargesubcategory.md deleted file mode 100644 index 207fd884f..000000000 --- a/specification/columns/chargesubcategory.md +++ /dev/null @@ -1,64 +0,0 @@ -# Charge Subcategory - -Charge Subcategory indicates what kind of usage or [*adjustment*](#glossary:adjustment) the [*row*](#glossary:row) represents. Charge Subcategory is a supplemental detail to the [Charge Category](#chargecategory). It provides additional context to describe the primary category of charge. - -This linkage to the parent Charge Category means that for every entry under Charge Category, there can be a corresponding Charge Subcategory that further refines the nature of the charge. It's a nested level of detail that allows users to see not just what type of charge was incurred. Current sub-categorization currently applies to Charge Category values "Usage" and "Adjustment". Support for others will be added as needed. - -When Charge Category is "Usage" and the charge is related to a [*commitment*](#glossary:commitment), the Charge Subcategory indicates whether the row represents committed usage or is an [*amortized*](#glossary:amortization) charge for the unused portion of the *commitment*. Charge Subcategory is commonly used for scenarios like calculating *commitment* utilization when Charge Category is "Usage". - -When Charge Category is "Adjustment", the Charge Subcategory indicates what kind of after-the-fact *adjustment* the record represents and is commonly used to identify changes like credits and refunds. - -ChargeSubcategory MUST follow the requirements listed below: - -* The ChargeSubcategory column MUST be present in the billing data when the provider supports sub-categorization of the [Charge Category](#chargecategory) values. -* ChargeSubcategory is of type String and MUST be one of the allowed values. -* ChargeSubcategory MUST NOT be null when ChargeCategory is "Usage" and the charge is covered by a *commitment*. - * When a usage charge is covered by a *commitment*, ChargeSubcategory MUST be "Used Commitment". - * When a *commitment* is not used, fully used, or partially used within the committed period ChargeSubcategory MUST be "Unused Commitment" for the unused usage charge. -* ChargeSubcategory MUST be null when ChargeCategory is "Usage" and is not covered by a *commitment*. -* ChargeSubcategory MUST NOT be null when ChargeCategory is "Adjustment". - * When an *adjustment* applies to a specific item, the corresponding FOCUS columns that identify that item MUST NOT be null and MUST match the applicable item details the *adjustment* pertains to. -* ChargeSubcategory MUST be null when ChargeCategory is "Purchase" or "Tax". - -## Column ID - -ChargeSubcategory - -## Display Name - -Charge Subcategory - -## Description - -Indicates what kind of usage or *adjustment* the *row* represents. - -## Content Constraints - -| Constraint | Value | -| :-------------- | :------------- | -| Column type | Dimension | -| Feature level | Conditional | -| Allows nulls | True | -| Data type | String | -| Value format | Allowed values | - -Allowed values when ChargeCategory is "Usage": - -| Value | Description | -| :---------------- | :------------------------------------------------------------------------------------- | -| On-Demand | Usage charges that are not associated with a commitment | -| Used Commitment | Usage charges that are associated with consumption of a commitment's underlying basis. | -| Unused Commitment | Amortized usage charges for the portion of a commitment that has not been used. For example, if an organization has a commitment-based discount that is not fully utilized, the unused portion falls under this category. It highlights an area where the organization is not fully leveraging its commitments, which could be a lost cost-saving opportunity. | - -Allowed values when ChargeCategory is "Adjustment": - -| Value | Description | -| :----------------- | :-----------------------------------------------------| -| Refund | Negative charges that were previously billed and are being returned by the provider. Providers can have multiple types of refunds such as resolving a tax error or for returned or exchanged commitment-based discounts. | -| Credit | Negative charges granted by the provider for various scenarios, like negotiated benefits, usage discounts, or promotional credits. | -| Rounding Error | Positive or negative charges that are needed to ensure raw billing data aggregations match the total cost on the invoice, which may be rounded. | -| General Adjustment | Positive or negative charges the provider applies that do not fall into other adjustment category values. | - -## Introduced (version) - -1.0-preview diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index cbc5835a7..14686004d 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -15,7 +15,6 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "chargefrequency.md",1 !INCLUDE "chargeperiodend.md",1 !INCLUDE "chargeperiodstart.md",1 -!INCLUDE "chargesubcategory.md",1 !INCLUDE "commitmentdiscountcategory.md",1 !INCLUDE "commitmentdiscountid.md",1 !INCLUDE "commitmentdiscountname.md",1 diff --git a/specification/columns/contractedcost.md b/specification/columns/contractedcost.md index 63f98e778..5693c5abc 100644 --- a/specification/columns/contractedcost.md +++ b/specification/columns/contractedcost.md @@ -7,7 +7,7 @@ The ContractedCost column MUST be present in the billing data and MUST NOT be nu In cases where the ContractedUnitPrice is present and null, the following applies: * The ContractedCost of a charge calculated based on other charges (e.g., when the [ChargeCategory](#chargecategory) is "Tax") MUST be calculated based on the ContractedCost of those related charges. -* The ContractedCost of a charge unrelated to other charges (e.g., when the [ChargeSubcategory](#chargesubcategory) is "Credit") MUST match the [BilledCost](#billedcost). +* The ContractedCost of a charge unrelated to other charges (e.g., when the [ChargeCategory](#chargecategory) is "Credit") MUST match the [BilledCost](#billedcost). ## Column ID diff --git a/specification/columns/effectivecost.md b/specification/columns/effectivecost.md index 4e02fb33d..4ebe952b6 100644 --- a/specification/columns/effectivecost.md +++ b/specification/columns/effectivecost.md @@ -12,7 +12,7 @@ The EffectiveCost column MUST be present in the billing data and MUST NOT be nul In cases where the [ChargeCategory](#chargecategory) is not "Usage" or "Purchase", the following applies: * The EffectiveCost MUST be calculated based on the EffectiveCost of the related charges if the charge is calculated based on other charges (e.g. [ChargeCategory](#chargecategory) is "Tax"). -* The EffectiveCost MUST match the [BilledCost](#billedcost) if the charge is unrelated to other charges (e.g. [ChargeSubcategory](#chargesubcategory) is "Credit"). +* The EffectiveCost MUST match the [BilledCost](#billedcost) if the charge is unrelated to other charges (e.g. [ChargeCategory](#chargecategory) is "Credit"). ## Column ID diff --git a/specification/columns/listcost.md b/specification/columns/listcost.md index f4c0765b0..76ae376c7 100644 --- a/specification/columns/listcost.md +++ b/specification/columns/listcost.md @@ -7,7 +7,7 @@ The ListCost column MUST be present in the billing data and MUST NOT be null. Th In cases where the ListUnitPrice is present and is null, the following applies: * The ListCost of a charge calculated based on other charges (e.g., when the [ChargeCategory](#chargecategory) is "Tax") MUST be calculated based on the ListCost of those related charges. -* The ListCost of a charge unrelated to other charges (e.g., when the [ChargeSubcategory](#chargesubcategory) is "Credit") MUST match the [BilledCost](#billedcost). +* The ListCost of a charge unrelated to other charges (e.g., when the [ChargeCategory](#chargecategory) is "Credit") MUST match the [BilledCost](#billedcost). ## Column ID diff --git a/specification/columns/pricingquantity.md b/specification/columns/pricingquantity.md index 8f8d6fd67..efca94f0d 100644 --- a/specification/columns/pricingquantity.md +++ b/specification/columns/pricingquantity.md @@ -2,7 +2,7 @@ The Pricing Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Pricing Unit](#pricingunit). Distinct from [Usage Quantity](#usagequantity) (complementary to [Usage Unit](#usageunit)), it focuses on pricing and cost, not *resource* and *service* consumption. -The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric. +The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric. ## Column ID diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md index 879fe325f..7cb7772a1 100644 --- a/specification/columns/usagequantity.md +++ b/specification/columns/usagequantity.md @@ -2,7 +2,7 @@ The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)) and focuses on *resource* and *service* consumption, not pricing and cost. -UsageQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeSubcategory](#chargesubcategory) is "Refund". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. +UsageQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. ## Column ID diff --git a/specification/use_case_library.md b/specification/use_case_library.md index 0d1731d57..d21c1afce 100644 --- a/specification/use_case_library.md +++ b/specification/use_case_library.md @@ -39,8 +39,8 @@ The following table contains a set of commonly performed FinOps scenarios that w | FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track unused commitment charges in any given time period so that I consider them in my future commitment planning or remedy them | CommitmentDiscountStatus (filter)
CommitmentDiscountID
BilledCost
ChargePeriodStart | | FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture. | ChargeType
ChargeDescription
ChargePeriodStart
Provider
ResourceType
SubAccountID
ServiceName | | FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture within a specific service | ChargeType
ChargeDescription
ChargePeriodStart
Provider
ResourceType
SubAccountID
ServiceName | -| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, identify total refunds within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeSubcategory | -| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, identify refunds across sub accounts within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeSubcategory
SubAccountID | +| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to identify total refunds within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeCategory
ChargeClass | +| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to identify refunds across sub accounts within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeCategory
ChargeClass
SubAccountID | | FinOps Practitioner | Workload Management & Automation | As a FinOps Practitioner, I need to do an analysis on compliance to data residency requirements across all regions | ChargePeriodStart
Provider
Region
SubAccountID | | Procurement | Data Analysis and Showback | As a person in Procurement, I need to understand what we are spending, across billing periods, across service categories to focus negotiations toward highest costing items | Provider
BillingAccountID
BillingAccountName
BillingCurrency
BilledCost
BillingPeriodStart
ServiceCategory
ServiceName | | Procurement, Finance, FinOps Practitioner | FinOps & Intersecting Frameworks | Multiple personas in an organization need to know the top SKU Codes based on spend, so that they can achieve multiple goals such as contract negotiation, SKU based forecasting, or high unit cost cleanup activities. | ChargePeriodStart
ChargePeriodEnd
ListCost
PricingUnit
ListUnitPrice
PricingQuantity
SKUId
SKUPriceId
Provider | diff --git a/supporting_content/attributes/discount_handling.md b/supporting_content/attributes/discount_handling.md index 588359612..4eac11eae 100644 --- a/supporting_content/attributes/discount_handling.md +++ b/supporting_content/attributes/discount_handling.md @@ -156,8 +156,8 @@ TBD - We have not yet discussed if there are any special nuances to how spot pricing works that should be explicitly incorporated into Discount Handling beyond identification of spot-priced charges. - Where does GCP's sustained usage discount fall under? Maybe the same as spot instance, in which case, **Usage-based discounts**? - - Since GCP SUDs are an after-the-fact discount that includes a negative charge, they're being tracked as ChargeCategory = `Adjustment` and ChargeSubcategory = `Credit`. - - In the main spec content, SUDs are covered by the "Any price or cost reductions that are awarded after the fact are identified as a `Credit` Charge Subcategory" sentence. + - Since GCP SUDs are an after-the-fact discount that includes a negative charge, they're being tracked as ChargeCategory = `Credit`. + - In the main spec content, SUDs are covered by the "Any price or cost reductions that are awarded after the fact are identified as a `Credit` Charge Category" sentence. - Microsoft discounts include: - Azure consumption discounts diff --git a/supporting_content/columns/chargecategory.md b/supporting_content/columns/chargecategory.md index c4047d6d2..735bbd92b 100644 --- a/supporting_content/columns/chargecategory.md +++ b/supporting_content/columns/chargecategory.md @@ -8,7 +8,7 @@ Current column mappings found in available data sets: | --------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AWS | CUR | `bill/BillType` (Anniversary, Purchase, Refund)
`lineItem/LineItemType` (Usage, Tax, BundledDiscount, Credit, Discount, DiscountedUsage, Fee, Refund, RIFee, SavingsPlanUpfrontFee, SavingsPlanRecurringFee, SavingsPlanCoveredUsage, SavingsPlanNegation) | | GCP | BigQuery Billing Export | `Cost type` (regular, tax, adjustment, or rounding error) | -| Microsoft | Cost details | `ChargeType` (Purchase, Usage, Refund, Adjustment, Tax?)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) | +| Microsoft | Cost details | `ChargeCategory` (Purchase, Usage, Refund, Adjustment, Tax?)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) | ## Example usage scenarios @@ -149,12 +149,12 @@ Permutations: ### Examples of how Charge Type relates to Pricing Category / Charge Frequency columns -| Scenario | ChargeCategory | ChargeSubcategory | PricingCategory | ChargeFrequency | CommitmentDisocuntUsage | -| ------------------------------------------------------------ | -------------- | ----------------- | --------------- | --------------- | ----------------------- | -| Upfront discount purchase | Purchase | NULL | Standard | One-time | NULL | -| Partial Upfront discount monthly fee | Purchase | NULL | Standard | Recurring | NULL | -| Usage covered by upfront portion of partial upfront discount | Usage | NULL | Committed | Usage-based | Unused | -| Unused commitment of partial upfront discount | Usage | NULL | Committed | Usage-based | Used | -| Usage not covered by discount | Usage | On-Demand | Standard | Usage-based | NULL | -| Refund | Adjustment | Refund | NULL | One-time | NULL | -| Usage invoice tax charge | Tax | NULL | NULL | Recurring | NULL | +| Scenario | ChargeCategory | PricingCategory | Charge Frequency | +| ------------------------------------------------------------ | -------------- | ---------------- | ---------------- | +| Upfront discount purchase | Purchase | On-Demand | One-time | +| Partial Upfront discount monthly fee | Purchase | On-Demand | Recurring | +| Usage covered by upfront portion of partial upfront discount | Usage | Commitment-based | Usage-based | +| Unused commitment of partial upfront discount | Usage | Commitment-based | Usage-based | +| Usage not covered by discount | Usage | On-Demand | Usage-based | +| Refund | Adjustment | NULL | One-time | +| Usage invoice tax charge | Tax | NULL | Recurring | diff --git a/supporting_content/columns/chargesubcategory.md b/supporting_content/columns/chargesubcategory.md deleted file mode 100644 index de96692d0..000000000 --- a/supporting_content/columns/chargesubcategory.md +++ /dev/null @@ -1,39 +0,0 @@ -# Column: ChargeSubcategory - -## Example provider mappings - -Current column mappings found in available data sets: - -| Provider | Data set | Column | -| --------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| AWS | CUR | `bill/BillType` (Refund)
`lineItem/LineItemType` (Tax, Credit, Discount, DiscountedUsage, Fee, Refund, RIFee, SavingsPlanUpfrontFee, SavingsPlanRecurringFee, SavingsPlanCoveredUsage, SavingsPlanNegation) | -| GCP | BigQuery Billing Export | `Cost type` (tax, adjustment, or rounding error) | -| Microsoft | Cost details | `ChargeCategory` (Refund)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) -| Microsoft | Cost Details |`RoundingAdjustment` (RoundingAdjustment) | - -## Example usage scenarios - -Current values observed in billing data for various scenarios: - -| Provider | Current value | ChargeCategory | Scenario | -| --------- | ---------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| AWS | Refund | Adjustment | | -| GCP | adjustment | Adjustment | ![Screenshot of GCP cost details with type and mode columns.](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/assets/399533/af90e4cd-f3c0-448a-bb0f-0249bcf7135c)
Example 1:
Description: "Billing correction - Adjustment for project X for incorrect Flexible CUD charge"
Mode: "MANUAL_ADJUSTMENT"
Type: "GENERAL_ADJUSTMENT" | -| GCP | rounding_error | Adjustment | These show up as monthly rows without a project as a credit | -| GCP | credit | Adjustment | Fields: type, name, amount, full_name, id
![Screenshot of a table with a type column and 5 rows of example values](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/assets/399533/15bcc210-5a36-473b-aeac-c1d2682dfdc8) | | -| Microsoft | Refund | Adjustment | Refund for exchange of commited use such as exchanging or refunding a reservation | -| Microsoft | Adjustment | Billing Correction | Credit provided back by the provider for incorrect billing. | -| Microsoft | Credit | Adjustment | Credit applied for good will or promotional credit or service level violation credits | - -## Discussion / Scratch space - -- What adjustment categories do we need to group? -- Do we need to normalize adjustment categories? -- Refunds - $s coming back after the original charge -- Credits are typically based on agreements for migration of workloads, or promotional items negotiated with the provider -- Balance transfers - how do you show what a balance transfer is if in the unliely event you close an account with a positive value and open a new account - -### Example mappings for normalized values - -| Provider | Usage | Purchase | Adjustment | Tax | -| --------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------ | --- | diff --git a/supporting_content/columns/pricingcategory.md b/supporting_content/columns/pricingcategory.md index d899a6e07..d5b286f0d 100644 --- a/supporting_content/columns/pricingcategory.md +++ b/supporting_content/columns/pricingcategory.md @@ -33,46 +33,46 @@ Current values observed in billing data for various scenarios: ## Discussion Topics -* Goal of the column is to enable practitioners to identify charges that have reduced prices vs. not. - * The most common question for this column is to identify commitment-based discounts and spot separate from on-demand. -* In 0.5, we didn't have enough time to close on how spot would be included: - * Someone mentioned that "spot" was a marketing term, so we tried to avoid it. - * We discussed values like "Preemptible" (confusing), "Interruptible" (not a pricing model), "Market-Based", "Variable", and "Dynamic". Ultimately, we agreed on "Dynamic". - * Then we questioned whether it "Dynamic" would be clear enough to practitioners who are looking for spot usage. -* In 1.0: - * We brought PricingModel back into discussion and had the same issues with "spot" being clearly understood as "Dynamic" so we decided to focus on other columns first. - * Over time, we got several requests to add a "PricingModel" column (that name explicitly), so we brought it back into discussion again. - * We agreed to add PricingModel as-is (with spot showing as "Dynamic"). -* While in PR, one member shared a link to IBM's documentation about how you're charged: https://cloud.ibm.com/docs/billing-usage?topic=billing-usage-charges - * IBM talks about Fixed, Metered, Tiered, and Reserved values. - * We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. - * The main concern about bringing these values in is that to get the on-demand costs, you'd have to look at 2 values, which makes it more complicated for practitioners. -* There was a poll with all members to determine if we should merge "Fixed" and "On-Demand" pricing options since they sounded near identical. - * 8 preferred merging and 3 preferred keeping them separate, so we decided to merge them. - * This was also discussed in the weekly member meeting, where people questioned using "On-Demand" for things that don't have a "pricing" model. - * We decided to use null when there is no price (SkuPriceId is null). - * As a note, multiple people have commented on nulls being more difficult for data analysis (since there's no clear meaning to why it's null). We did not have time to discuss this in the meeting, but it's something we should discuss in the future as it applies to all columns. - * The group also asked to add an "Other" option to account for any new pricing model that may come up in the future. -* Later, while still in PR, there was a concern about "dynamic on-demand pricing": - * This brought the IBM values of Fixed, Metered, Tiered, and Reserved back into the discussion as those were a more detailed version of what we were trying to do. - * We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. - * A few weeks before this, we as a group decided to use the term "Category" for normalized types and we also introduced a ChargeSubcategory column as the next level grouping. - * Based on this Category/Subcategory pattern, we decided to break PricingModel into PricingCategory and PricingSubcategory, adding a more detailed breakdown of each category. - * Regarding "dynamic on-demand", this isn't possible given our current definitions (always-changing price vs. predetermined set price). - * As part of these discussions, we also discussed whether "On-Demand" was the right term. - * We discussed "Standard" as a replacement, but agreed "On-Demand" is more common and clear for the pricing model of pricing that is based on the published price for the billing account. (Note: Tiered pricing (aka volume-based discounts) are also predetermined and published, so they are also "On-Demand" by our definition.) - * We felt "Standard" was more clear as a differentiator from "Tiered" pricing. Another alternative was "Flat Rate". - * We also discussed whether to use "Commitment-Based" or "Discounted". - * If we use "Discounted", then any future discounting strategy could get rolled into a single column without the need to change values. - * The main downside of this is that, given how important commitment-based discounts are (and the fact that they are one of the primary reasons for adding this column), we felt it was important to call them out explicitly. - * Additionally, given different discount strategies will price things differently, it's also important that we distinguish the separate pricing models at the top level. - * We also didn't have any other clear examples that would fall into "Discounted" pricing that would be meaningfully grouped together in a way that practitioners would want to see together and not distinguished separately from their committed costs. - * We also discussed the term "Dynamic" and whether it was clear enough. - * During this, we discovered that "spot" is not a marketing term and is in fact a pricing construct for an always-changing price that a good or service can be immediately sold at. - * We discussed replacing "Dynamic" with "Spot", but agreed that "Dynamic" is more inclusive of other types of dynamic pricing models that may be introduced in the future and would likely be desirable to be grouped together. - * Given we cannot predict all pricing models that will be introduced in the future, we decided to also add "Other" in each subcategory. -* Unfortunately, we didn't think we had enough time to close PricingSubcategory, so we decided to hold that for after 1.0. -* On April 3, 2024, we agreed to change "On-Demand" to "Standard" and "Commitment-Based" to "Committed". +- Goal of the column is to enable practitioners to identify charges that have reduced prices vs. not. + - The most common question for this column is to identify commitment-based discounts and spot separate from on-demand. +- In 0.5, we didn't have enough time to close on how spot would be included: + - Someone mentioned that "spot" was a marketing term, so we tried to avoid it. + - We discussed values like "Preemptible" (confusing), "Interruptible" (not a pricing model), "Market-Based", "Variable", and "Dynamic". Ultimately, we agreed on "Dynamic". + - Then we questioned whether it "Dynamic" would be clear enough to practitioners who are looking for spot usage. +- In 1.0: + - We brought PricingModel back into discussion and had the same issues with "spot" being clearly understood as "Dynamic" so we decided to focus on other columns first. + - Over time, we got several requests to add a "PricingModel" column (that name explicitly), so we brought it back into discussion again. + - We agreed to add PricingModel as-is (with spot showing as "Dynamic"). +- While in PR, one member shared a link to IBM's documentation about how you're charged: https://cloud.ibm.com/docs/billing-usage?topic=billing-usage-charges + - IBM talks about Fixed, Metered, Tiered, and Reserved values. + - We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. + - The main concern about bringing these values in is that to get the on-demand costs, you'd have to look at 2 values, which makes it more complicated for practitioners. +- There was a poll with all members to determine if we should merge "Fixed" and "On-Demand" pricing options since they sounded near identical. + - 8 preferred merging and 3 preferred keeping them separate, so we decided to merge them. + - This was also discussed in the weekly member meeting, where people questioned using "On-Demand" for things that don't have a "pricing" model. + - We decided to use null when there is no price (SkuPriceId is null). + - As a note, multiple people have commented on nulls being more difficult for data analysis (since there's no clear meaning to why it's null). We did not have time to discuss this in the meeting, but it's something we should discuss in the future as it applies to all columns. + - The group also asked to add an "Other" option to account for any new pricing model that may come up in the future. +- Later, while still in PR, there was a concern about "dynamic on-demand pricing": + - This brought the IBM values of Fixed, Metered, Tiered, and Reserved back into the discussion as those were a more detailed version of what we were trying to do. + - We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. + - A few weeks before this, we as a group decided to use the term "Category" for normalized types and we also introduced a ChargeSubcategory column as the next level grouping. + - Update: In February/April 2024, it was decided that we would remove ChargeSubcategory for 1.0 GA. We may bring it back later once we have a better idea of what ChargeCategory breakdowns might be. + - Based on this Category/Subcategory pattern, we decided to break PricingModel into PricingCategory and PricingSubcategory, adding a more detailed breakdown of each category. + - Regarding "dynamic on-demand", this isn't possible given our current definitions (always-changing price vs. predetermined set price). + - As part of these discussions, we also discussed whether "On-Demand" was the right term. + - We discussed "Standard" as a replacement, but agreed "On-Demand" is more common and clear for the pricing model of pricing that is based on the published price for the billing account. (Note: Tiered pricing (aka volume-based discounts) are also predetermined and published, so they are also "On-Demand" by our definition.) + - We felt "Standard" was more clear as a differentiator from "Tiered" pricing. Another alternative was "Flat Rate". + - We also discussed whether to use "Commitment-Based" or "Discounted". + - If we use "Discounted", then any future discounting strategy could get rolled into a single column without the need to change values. + - The main downside of this is that, given how important commitment-based discounts are (and the fact that they are one of the primary reasons for adding this column), we felt it was important to call them out explicitly. + - Additionally, given different discount strategies will price things differently, it's also important that we distinguish the separate pricing models at the top level. + - We also didn't have any other clear examples that would fall into "Discounted" pricing that would be meaningfully grouped together in a way that practitioners would want to see together and not distinguished separately from their committed costs. + - We also discussed the term "Dynamic" and whether it was clear enough. + - During this, we discovered that "spot" is not a marketing term and is in fact a pricing construct for an always-changing price that a good or service can be immediately sold at. + - We discussed replacing "Dynamic" with "Spot", but agreed that "Dynamic" is more inclusive of other types of dynamic pricing models that may be introduced in the future and would likely be desirable to be grouped together. + - Given we cannot predict all pricing models that will be introduced in the future, we decided to also add "Other" in each subcategory. +- Unfortunately, we didn't think we had enough time to close PricingSubcategory, so we decided to hold that for after 1.0. Open issues: From 4d77bd2664d1a9ef650597b7288d9674fed023e3 Mon Sep 17 00:00:00 2001 From: Graham Date: Fri, 26 Apr 2024 04:07:14 +1000 Subject: [PATCH 44/65] FOCUS #330: Update chargeclass value from "Regular" to "Standard" (#410) Pricing category had the value "on-demand" changed to "Standard", so recommend keeping consistency in naming and have charge class value as "Standard" instead of "Regular" Co-authored-by: Alex Hullah --- specification/columns/chargeclass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/columns/chargeclass.md b/specification/columns/chargeclass.md index fbe619814..bdeab4609 100644 --- a/specification/columns/chargeclass.md +++ b/specification/columns/chargeclass.md @@ -30,7 +30,7 @@ Allowed values: | Value | Description | | :--------- | :------------------------------------| -| Regular | Standard charges for services used or purchased. | +| Standard | Standard charges for services used or purchased. | | Correction | Modification to one or more previous charges, like refunds and credit modifications. | ## Introduced (version) From 6c9fd329c25f50404146e07d207a9d445e42331a Mon Sep 17 00:00:00 2001 From: Christopher Harris Date: Fri, 26 Apr 2024 08:03:13 -0700 Subject: [PATCH 45/65] Further specify inclusive/exclusive datetime values for BillingPeriod{Start,End} and ChargePeriod{Start,End} (#398) Issue: https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/issues/380 # Change Further clarify within the column definition that various columns MUST contain inclusive/exclusive datetimes: - BillingPeriodStart -> inclusive - BillingPeriodEnd -> exclusive - ChargePeriodStart -> inclusive - ChargePeriodEnd -> exclusive --------- Co-authored-by: Alex Hullah Co-authored-by: Udam Dewaraja Co-authored-by: Joaquin --- specification/columns/billingperiodend.md | 6 +++--- specification/columns/billingperiodstart.md | 6 +++--- specification/columns/chargeperiodend.md | 6 +++--- specification/columns/chargeperiodstart.md | 6 +++--- specification/glossary.md | 8 ++++++++ 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/specification/columns/billingperiodend.md b/specification/columns/billingperiodend.md index a94b09220..61cf8981e 100644 --- a/specification/columns/billingperiodend.md +++ b/specification/columns/billingperiodend.md @@ -1,8 +1,8 @@ # Billing Period End -Billing Period End represents the end date and time of the [*billing period*](#glossary:billing-period). +Billing Period Start represents the [*exclusive*](#glossary:exclusivebound) end date and time of a [*billing period*](#glossary:billing-period). For example, a time period where [BillingPeriodStart](#glossary:billingperiodstart) is '2024-01-01T00:00:00Z' and BillingPeriodEnd is '2024-02-01T00:00:00Z' includes charges for January, since BillingPeriodStart is [*inclusive*](#glossary:inclusivebound), but does not include charges for February since BillingPeriodEnd is *exclusive*. -The BillingPeriodEnd column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. BillingPeriodEnd column MUST conform to [Date/Time Format](#date/timeformat) requirements. The sum of the [BilledCost](#billedcost) column for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). +The BillingPeriodEnd column MUST be present in the billing data. This column MUST be of type [Date/Time Format](#date/timeformat), MUST be an *exclusive* value, and MUST NOT contain null values. The sum of the [BilledCost](#billedcost) column for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). ## Column ID @@ -14,7 +14,7 @@ Billing Period End ## Description -The end date and time of the *billing period*. +The [*exclusive*](#glossary:exclusivebound) end date and time of a [*billing period*](#glossary:billing-period). ## Content Constraints diff --git a/specification/columns/billingperiodstart.md b/specification/columns/billingperiodstart.md index c55a3b62a..27f125b8c 100644 --- a/specification/columns/billingperiodstart.md +++ b/specification/columns/billingperiodstart.md @@ -1,8 +1,8 @@ # Billing Period Start -Billing Period Start represents the start date and time of the [*billing period*](#glossary:billing-period). +Billing Period Start represents the [*inclusive*](#glossary:inclusivebound) start date and time of a [*billing period*](#glossary:billing-period). For example, a time period where BillingPeriodStart is '2024-01-01T00:00:00Z' and [BillingPeriodEnd](#billingperiodend) is '2024-02-01T00:00:00Z' includes charges for January, since BillingPeriodStart is inclusive, but does not include charges for February since BillingPeriodEnd is [*exclusive*](#glossary:exclusivebound). -The BillingPeriodStart column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. BillingPeriodStart column MUST conform to [Date/Time Format](#date/timeformat) requirements. The sum of the [BilledCost](#billedcost) metric for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). +The BillingPeriodStart column MUST be present in the billing data, MUST be of type [Date/Time Format](#date/timeformat), MUST be an *inclusive* value, and MUST NOT contain null values. The sum of the [BilledCost](#billedcost) metric for [*rows*](#glossary:row) in a given *billing period* MUST match the sum of the invoices received for that *billing period* for a [*billing account*](#glossary:billing-account). ## Column ID @@ -14,7 +14,7 @@ Billing Period Start ## Description -The beginning date and time of the *billing period*. +The [*inclusive*](#glossary:inclusivebound) start date and time of a [*billing period*](#glossary:billing-period). ## Content Constraints diff --git a/specification/columns/chargeperiodend.md b/specification/columns/chargeperiodend.md index 94aa07eb6..f017bb747 100644 --- a/specification/columns/chargeperiodend.md +++ b/specification/columns/chargeperiodend.md @@ -1,8 +1,8 @@ # Charge Period End -Charge Period End represents the end date and time of the [*charge period*](#glossary:chargeperiod). +Charge Period End represents the [*exclusive*](#glossary:exclusivebound) end date and time of a [*charge period*](#glossary:chargeperiod). For example, a time period where [ChargePeriodStart](#chargeperiodstart) is '2024-01-01T00:00:00Z' and ChargePeriodEnd is '2024-01-02T00:00:00Z' includes charges for January 1, since ChargePeriodStart is [*inclusive*](#glossary:inclusivebound), but does not include charges for January 2 since ChargePeriodEnd is *exclusive*. -The ChargePeriodEnd column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. ChargePeriodEnd column MUST conform to [Date/Time Format](#date/timeformat) requirements. +ChargePeriodEnd MUST be present in the billing data, MUST be of type Date/Time, MUST be an *exclusive* value, and MUST NOT contain null values. ## Column ID @@ -14,7 +14,7 @@ Charge Period End ## Description -The end date and time of a *charge period*. +The [*exclusive*](#glossary:exclusivebound) end date and time of a charge period. ## Content constraints diff --git a/specification/columns/chargeperiodstart.md b/specification/columns/chargeperiodstart.md index 7b53770f8..3c9347d07 100644 --- a/specification/columns/chargeperiodstart.md +++ b/specification/columns/chargeperiodstart.md @@ -1,8 +1,8 @@ # Charge Period Start -Charge Period Start represents the starting date and time of the [*charge period*](#glossary:chargeperiod). +Charge Period Start represents the [*inclusive*](#glossary:inclusivebound) start date and time within a [*charge period*](#glossary:chargeperiod). For example, a time period where ChargePeriodStart is '2024-01-01T00:00:00Z' and [ChargePeriodEnd](#chargeperiodend) is '2024-01-02T00:00:00Z' includes charges for January 1, since ChargePeriodStart is *inclusive*, but does not include charges for January 2 since ChargePeriodEnd is [*exclusive*](#glossary:exclusivebound). -The ChargePeriodStart column MUST be present in the billing data. This column MUST be of type Date/Time and MUST NOT contain null values. ChargePeriodStart column MUST conform to [Date/Time Format](#date/timeformat) requirements. +ChargePeriodStart MUST be present in the billing data, MUST be of type Date/Time, MUST be an *inclusive* value, and MUST NOT contain null values. ## Column ID @@ -14,7 +14,7 @@ Charge Period Start ## Description -The beginning date and time of a *charge period*. +The [*inclusive*](#glossary:inclusivebound) start date and time within a [*charge period*](#glossary:chargeperiod). ## Content constraints diff --git a/specification/glossary.md b/specification/glossary.md index 1724c7a0e..2aa21ba2e 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -60,6 +60,10 @@ A specification-defined categorical attribute that provides context or categoriz Cost inclusive of the impacts of all reduced rates and discounts, augmented with the amortization of relevant purchases (one-time or recurring) paid to cover future eligible charges. +Exclusive Bound + +A Date/Time Format value that is not contained within the ending bound of a time period. + Finalized Tag A tag with one tag value chosen from a set of possible tag values after being processed by a set of provider-defined or user-defined rules. @@ -68,6 +72,10 @@ A tag with one tag value chosen from a set of possible tag values after being pr An open-source specification that defines requirements for billing data. +Inclusive Bound + +A Date/Time Format value that is contained within the beginning bound of a time period. + Interruptible A category of compute resources that can be paused or terminated by the CSP within certain criteria, often advertised at reduced unit pricing when compared to the equivalent non-interruptible resource. From bf6034e42da9cf9b0a6f82ac88e67288f9a8b0f6 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Mon, 29 Apr 2024 13:59:01 +1000 Subject: [PATCH 46/65] Clarify NULL handling for placeholders (#421) As discussed regarding #417. Added a little more clarifying language to say don't use placeholders to represent NULLs --------- Signed-off-by: Mike Fuller Co-authored-by: Michael Flanakin Co-authored-by: Joaquin --- specification/attributes/null_handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/attributes/null_handling.md b/specification/attributes/null_handling.md index 3805d1fc2..f3ad55e73 100644 --- a/specification/attributes/null_handling.md +++ b/specification/attributes/null_handling.md @@ -19,7 +19,7 @@ Indicates how to handle columns that don't have a value. ## Requirements * Columns MUST use NULL when there isn't a value that can be specified for a nullable column. -* Columns MUST NOT use empty strings or placeholder values such as 0 for numeric columns or "Not Applicable" for string columns, regardless of whether the column allows nulls or not. +* Columns MUST NOT use empty strings or placeholder values such as 0 for numeric columns or "Not Applicable" for string columns to represent a null or not having a value, regardless of whether the column allows nulls or not. ## Exceptions From 21dc0b390bdd7ae08475611f91d87f7dd3b6676a Mon Sep 17 00:00:00 2001 From: Irena Jurica Date: Mon, 29 Apr 2024 06:23:23 +0200 Subject: [PATCH 47/65] FOCUS #366: SkuId, SkuPriceId, and Pricing-related columns review due to ChargeCategory and ChargeClass cleanup (#413) ChargeCategory and ChargeClass cleanup impacted multiple columns. Based on current ChargeCategory references, the following columns must be revisited: - SkuId - SkuPriceId - ContractedUnitPrice - ListUnitPrice - Pricingcategory - PricingUnit - PricingQuantity - UsageQuantity - UsageUnit - ListCost - ContractedCost - EffectiveCost --------- Co-authored-by: Michael Flanakin Co-authored-by: Alex Hullah Co-authored-by: Michael Flanakin Co-authored-by: Udam Dewaraja Co-authored-by: Joaquin --- CHANGELOG.md | 24 +++++- specification/attributes/discount_handling.md | 6 +- specification/columns/chargeclass.md | 4 +- specification/columns/contractedcost.md | 2 +- specification/columns/contractedunitprice.md | 2 +- specification/columns/listcost.md | 2 +- specification/columns/listunitprice.md | 2 +- specification/columns/pricingcategory.md | 2 +- specification/columns/pricingquantity.md | 2 +- specification/columns/pricingunit.md | 2 +- specification/columns/skuid.md | 2 +- specification/columns/skupriceid.md | 2 +- specification/columns/usagequantity.md | 2 +- specification/columns/usageunit.md | 2 +- supporting_content/columns/chargecategory.md | 20 ++--- supporting_content/columns/pricingcategory.md | 80 +++++++++---------- supporting_content/columns/skupriceid.md | 39 ++++++--- 17 files changed, 112 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdebd3988..aef0381c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,10 +39,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Clarified that effective cost does not mix or "blend" costs across multiple charges. - `ListUnitPrice` column updates: - Column is conditional and only required when the provider publishes a price list that excludes discounts. + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". - `PricingCategory` column updates: - Column is conditional and only required when the provider supports more than one pricing category value. - Changed "On-Demand" to "Standard". - Changed "Commitment-Based" to "Committed". + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". +- `PricingQuantity` + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". +- `PricingUnit` + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". - `ResourceId` column updates: - Column is conditional and only required when the provider supports billing based on provisioned resource instances. - `ResourceName` column updates: @@ -51,10 +61,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Column is conditional and only required when the provider supports billing based on provisioned resource instances and supports multiple "types" of resources. - `SkuId` column updates: - Column is conditional and only required when the provider publishes a SKU list. + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". - `SkuPriceId` column updates: - Column is conditional and only required when the provider publishes a SKU price list. - - Must not be null when `ChargeClass` is "Regular" - - Must not be null when `ChargeCategory` is "Credit" or "Adjustment" and the charge is associated with a specific `SkuPriceId`. + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". - `SubAccountId` column updates: - Column is conditional and only required when the provider supports a sub account construct. - `SubAccountName` column updates: @@ -63,9 +75,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Column is conditional and only required when the provider supports setting user- or provider-defined tags. - Tag keys that cannot have a value must use a boolean `true` as the tag value. - `UsageQuantity` column updates: - - Column is conditional and only required when the provider supports the measurement of usage. + - Column is conditional and only required when the provider supports the measurement of usage. + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". - `UsageUnit` column updates: - - Column is conditional and only required when the provider supports the measurement of usage. + - Column is conditional and only required when the provider supports the measurement of usage. + - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must be null when `ChargeCategory` is "Tax". **Fixed:** diff --git a/specification/attributes/discount_handling.md b/specification/attributes/discount_handling.md index ec723fdfc..79a3a7e2a 100644 --- a/specification/attributes/discount_handling.md +++ b/specification/attributes/discount_handling.md @@ -34,9 +34,9 @@ Indicates how to include and apply discounts to usage charges or rows. * Purchased discounts (e.g., commitment-based discounts) MUST be amortized. * The BilledCost MUST be 0 for any row where the commitment covers the entire cost for the charge period. * The EffectiveCost MUST include the portion of the amortized purchase cost that applies to this row. - * ChargeSubcategory MUST be "Used Commitment" for rows that received a reduced price from that commitment. - * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. ChargeSubcategory MUST be "Unused Commitment". - * The sum of the EffectiveCost for all "Used Commitment" and "Unused Commitment" rows for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. + * CommitmentDiscountStatus MUST be "Used" for rows that received a reduced price from that commitment. + * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. CommitmentDiscountStatus MUST be "Unused". + * The sum of the EffectiveCost for all rows where CommitmentDiscountStatus is "Used" or "Unused" for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. * Credits that are applied after the fact MUST use a ChargeCategory of "Credit". ## Exceptions diff --git a/specification/columns/chargeclass.md b/specification/columns/chargeclass.md index bdeab4609..1fbde4945 100644 --- a/specification/columns/chargeclass.md +++ b/specification/columns/chargeclass.md @@ -14,14 +14,14 @@ Charge Class ## Description -Indicates whether the row represents a regular charge or a correction to one or more previous charges, its primary use iis for differentiating refunds from normal usage. +Indicates whether the row represents a regular charge or a correction to one or more previous charges, its primary use is for differentiating refunds from normal usage. ## Content Constraints | Constraint | Value | | :-------------- | :------------- | | Column type | Dimension | -| Column required | True | +| Feature level | Mandatory | | Allows nulls | False | | Data type | String | | Value format | Allowed values | diff --git a/specification/columns/contractedcost.md b/specification/columns/contractedcost.md index 5693c5abc..33b56f225 100644 --- a/specification/columns/contractedcost.md +++ b/specification/columns/contractedcost.md @@ -2,7 +2,7 @@ Contracted Cost represents the cost calculated by multiplying [*contracted unit price*](#glossary:contracted-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). Contracted Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on negotiation activities, by comparing it with [List Cost](#listcost). If negotiated discounts are not applicable, the Contracted Cost defaults to the List Cost. -The ContractedCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ContractedUnitPrice](#contractedunitprice) is present and not null, multiplying the ContractedUnitPrice by PricingQuantity MUST produce the ContractedCost. +The ContractedCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ContractedUnitPrice](#contractedunitprice) is present and not null, multiplying the ContractedUnitPrice by PricingQuantity MUST produce the ContractedCost, except in cases of [ChargeClass](#chargeclass) "Correction", which may address PricingQuantity or any cost discrepancies independently. In cases where the ContractedUnitPrice is present and null, the following applies: diff --git a/specification/columns/contractedunitprice.md b/specification/columns/contractedunitprice.md index 298904775..25fc0e595 100644 --- a/specification/columns/contractedunitprice.md +++ b/specification/columns/contractedunitprice.md @@ -2,7 +2,7 @@ The Contracted Unit Price represents the agreed-upon unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, inclusive of negotiated discounts, if present, while excluding negotiated commitment-based discounts or any other discounts. This price is denominated in the [Billing Currency](#billingcurrency). The Contracted Unit Price is commonly used for calculating savings based on negotiation activities. If negotiated discounts are not applicable, the Contracted Unit Price defaults to the [List Unit Price](#listunitprice). -The ContractedUnitPrice column MUST be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ContractedUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost). +The ContractedUnitPrice column MUST be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost), except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. ## Column ID diff --git a/specification/columns/listcost.md b/specification/columns/listcost.md index 76ae376c7..a9ec757c2 100644 --- a/specification/columns/listcost.md +++ b/specification/columns/listcost.md @@ -2,7 +2,7 @@ List Cost represents the cost calculated by multiplying the [*list unit price*](#glossary:list-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). List Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on various rate optimization activities, by comparing it with [Billed Cost](#billedcost) and [Effective Cost](#effectivecost). -The ListCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ListUnitPrice](#listunitprice) is present and not null, multiplying the ListUnitPrice by PricingQuantity MUST produce the ListCost. +The ListCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ListUnitPrice](#listunitprice) is present and not null, multiplying the ListUnitPrice by PricingQuantity MUST produce the ListCost, except in cases of [ChargeClass](#chargeclass) "Correction", which may address PricingQuantity or any cost discrepancies independently. In cases where the ListUnitPrice is present and is null, the following applies: diff --git a/specification/columns/listunitprice.md b/specification/columns/listunitprice.md index 1f2c423e7..ea1295a42 100644 --- a/specification/columns/listunitprice.md +++ b/specification/columns/listunitprice.md @@ -2,7 +2,7 @@ The List Unit Price represents the suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, exclusive of any discounts. This price is denominated in the [Billing Currency](#billingcurrency). The List Unit Price is commonly used for calculating savings based on various rate optimization activities. -The ListUnitPrice column MUST be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When ListUnitPrice is present, it MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost). +The ListUnitPrice column MUST be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost), except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. ## Column ID diff --git a/specification/columns/pricingcategory.md b/specification/columns/pricingcategory.md index de8e1f991..4bd45e32f 100644 --- a/specification/columns/pricingcategory.md +++ b/specification/columns/pricingcategory.md @@ -5,7 +5,7 @@ Pricing Category describes the pricing model used for a charge at the time of us The PricingCategory column adheres to the following requirements: * PricingCategory MUST be present in the billing data when the provider supports more than one pricing category across all SKUs and MUST be of type String. -* PricingCategory MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MUST be null for other ChargeCategory values. +* PricingCategory MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. * PricingCategory MUST be one of the allowed values. * PricingCategory MUST be "Standard" when pricing is predetermined at the agreed upon rate for the [billing account](#glossary:billing-account). * PricingCategory MUST be "Committed" when [CommitmentDiscountId](#commitmentdiscountid) is not null. diff --git a/specification/columns/pricingquantity.md b/specification/columns/pricingquantity.md index efca94f0d..cd1761fc0 100644 --- a/specification/columns/pricingquantity.md +++ b/specification/columns/pricingquantity.md @@ -2,7 +2,7 @@ The Pricing Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Pricing Unit](#pricingunit). Distinct from [Usage Quantity](#usagequantity) (complementary to [Usage Unit](#usageunit)), it focuses on pricing and cost, not *resource* and *service* consumption. -The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric. +The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric, except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. ## Column ID diff --git a/specification/columns/pricingunit.md b/specification/columns/pricingunit.md index dbd3d992b..bfc88ce4a 100644 --- a/specification/columns/pricingunit.md +++ b/specification/columns/pricingunit.md @@ -2,7 +2,7 @@ The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how the provider rates measured usage and purchase quantities after applying pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Usage Unit](#usageunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. -The PricingUnit column MUST be present in the billing data. This column MUST be of type String. This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. +The PricingUnit column MUST be present in the billing data. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The PricingUnit value MUST be semantically equal to the corresponding pricing measurement unit value provided in: diff --git a/specification/columns/skuid.md b/specification/columns/skuid.md index 2ef0bd240..f63f66310 100644 --- a/specification/columns/skuid.md +++ b/specification/columns/skuid.md @@ -2,7 +2,7 @@ A SKU ID is a unique identifier that defines a provider-supported construct for organizing properties that are common across one or more [*SKU Prices*](#glossary:sku-price). SKU ID can be referenced on a catalog or [*price list*](#glossary:price-list) published by a provider to look up detailed information about the SKU. The composition of the properties associated with the SKU ID may differ across providers. Some providers may not support the [*SKU*](#glossary:sku) construct and instead associate all such properties directly with the *SKU Price*. SKU ID is commonly used for analyzing cost based on *SKU*-related properties above the pricing constructs. -The SkuId column MUST be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. The SkuId MUST NOT be null when [SkuPriceId](#skupriceid) is not null. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. +The SkuId column MUST be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. ## Column ID diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index 78c73341a..36aacbbe0 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -2,7 +2,7 @@ A SKU Price ID is a unique identifier that defines the unit price used to calculate the charge. SKU Price ID can be referenced on a [*price list*](#glossary:price-list) published by a provider to look up detailed information, including a corresponding list unit price. The composition of the properties associated with the SKU Price ID may differ across providers. SKU Price ID is commonly used for analyzing cost based on pricing properties such as Terms and Tiers. -The SkuPriceId column MUST be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Purchase" or "Usage" and [ChargeClass](#chargeclass) is "Regular". The SkuPriceId MUST NOT be null when [ChargeCategory](#chargecategory) is "Credit" or "Adjustment" and the charge is associated with a specific SkuPriceId. SkuPriceId MUST NOT be null when [ChargeClass](#chargeclass) is "Correction" and the correction is associated with a specific SkuPriceId. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. +The SkuPriceId column MUST be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. This column MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. ## Column ID diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md index 7cb7772a1..5475c8ed9 100644 --- a/specification/columns/usagequantity.md +++ b/specification/columns/usagequantity.md @@ -2,7 +2,7 @@ The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)) and focuses on *resource* and *service* consumption, not pricing and cost. -UsageQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. +UsageQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. ## Column ID diff --git a/specification/columns/usageunit.md b/specification/columns/usageunit.md index a9b40264a..967e1fe9d 100644 --- a/specification/columns/usageunit.md +++ b/specification/columns/usageunit.md @@ -2,7 +2,7 @@ The Usage Unit represents a provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service). Usage Unit complements the [Usage Quantity](#usagequantity) metric. It is often listed at a finer granularity or over a different time interval when compared to the [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. -The UsageUnit column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. UsageUnit MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" or "Purchase" and MAY be null for other ChargeCategory values. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. +The UsageUnit column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. ## Column ID diff --git a/supporting_content/columns/chargecategory.md b/supporting_content/columns/chargecategory.md index 735bbd92b..c4047d6d2 100644 --- a/supporting_content/columns/chargecategory.md +++ b/supporting_content/columns/chargecategory.md @@ -8,7 +8,7 @@ Current column mappings found in available data sets: | --------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AWS | CUR | `bill/BillType` (Anniversary, Purchase, Refund)
`lineItem/LineItemType` (Usage, Tax, BundledDiscount, Credit, Discount, DiscountedUsage, Fee, Refund, RIFee, SavingsPlanUpfrontFee, SavingsPlanRecurringFee, SavingsPlanCoveredUsage, SavingsPlanNegation) | | GCP | BigQuery Billing Export | `Cost type` (regular, tax, adjustment, or rounding error) | -| Microsoft | Cost details | `ChargeCategory` (Purchase, Usage, Refund, Adjustment, Tax?)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) | +| Microsoft | Cost details | `ChargeType` (Purchase, Usage, Refund, Adjustment, Tax?)

Related:
`PricingModel` (OnDemand, Reservation, SavingsPlan, Spot)
`Frequency` (OneTime, Recurring) | ## Example usage scenarios @@ -149,12 +149,12 @@ Permutations: ### Examples of how Charge Type relates to Pricing Category / Charge Frequency columns -| Scenario | ChargeCategory | PricingCategory | Charge Frequency | -| ------------------------------------------------------------ | -------------- | ---------------- | ---------------- | -| Upfront discount purchase | Purchase | On-Demand | One-time | -| Partial Upfront discount monthly fee | Purchase | On-Demand | Recurring | -| Usage covered by upfront portion of partial upfront discount | Usage | Commitment-based | Usage-based | -| Unused commitment of partial upfront discount | Usage | Commitment-based | Usage-based | -| Usage not covered by discount | Usage | On-Demand | Usage-based | -| Refund | Adjustment | NULL | One-time | -| Usage invoice tax charge | Tax | NULL | Recurring | +| Scenario | ChargeCategory | ChargeSubcategory | PricingCategory | ChargeFrequency | CommitmentDisocuntUsage | +| ------------------------------------------------------------ | -------------- | ----------------- | --------------- | --------------- | ----------------------- | +| Upfront discount purchase | Purchase | NULL | Standard | One-time | NULL | +| Partial Upfront discount monthly fee | Purchase | NULL | Standard | Recurring | NULL | +| Usage covered by upfront portion of partial upfront discount | Usage | NULL | Committed | Usage-based | Unused | +| Unused commitment of partial upfront discount | Usage | NULL | Committed | Usage-based | Used | +| Usage not covered by discount | Usage | On-Demand | Standard | Usage-based | NULL | +| Refund | Adjustment | Refund | NULL | One-time | NULL | +| Usage invoice tax charge | Tax | NULL | NULL | Recurring | NULL | diff --git a/supporting_content/columns/pricingcategory.md b/supporting_content/columns/pricingcategory.md index d5b286f0d..d899a6e07 100644 --- a/supporting_content/columns/pricingcategory.md +++ b/supporting_content/columns/pricingcategory.md @@ -33,46 +33,46 @@ Current values observed in billing data for various scenarios: ## Discussion Topics -- Goal of the column is to enable practitioners to identify charges that have reduced prices vs. not. - - The most common question for this column is to identify commitment-based discounts and spot separate from on-demand. -- In 0.5, we didn't have enough time to close on how spot would be included: - - Someone mentioned that "spot" was a marketing term, so we tried to avoid it. - - We discussed values like "Preemptible" (confusing), "Interruptible" (not a pricing model), "Market-Based", "Variable", and "Dynamic". Ultimately, we agreed on "Dynamic". - - Then we questioned whether it "Dynamic" would be clear enough to practitioners who are looking for spot usage. -- In 1.0: - - We brought PricingModel back into discussion and had the same issues with "spot" being clearly understood as "Dynamic" so we decided to focus on other columns first. - - Over time, we got several requests to add a "PricingModel" column (that name explicitly), so we brought it back into discussion again. - - We agreed to add PricingModel as-is (with spot showing as "Dynamic"). -- While in PR, one member shared a link to IBM's documentation about how you're charged: https://cloud.ibm.com/docs/billing-usage?topic=billing-usage-charges - - IBM talks about Fixed, Metered, Tiered, and Reserved values. - - We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. - - The main concern about bringing these values in is that to get the on-demand costs, you'd have to look at 2 values, which makes it more complicated for practitioners. -- There was a poll with all members to determine if we should merge "Fixed" and "On-Demand" pricing options since they sounded near identical. - - 8 preferred merging and 3 preferred keeping them separate, so we decided to merge them. - - This was also discussed in the weekly member meeting, where people questioned using "On-Demand" for things that don't have a "pricing" model. - - We decided to use null when there is no price (SkuPriceId is null). - - As a note, multiple people have commented on nulls being more difficult for data analysis (since there's no clear meaning to why it's null). We did not have time to discuss this in the meeting, but it's something we should discuss in the future as it applies to all columns. - - The group also asked to add an "Other" option to account for any new pricing model that may come up in the future. -- Later, while still in PR, there was a concern about "dynamic on-demand pricing": - - This brought the IBM values of Fixed, Metered, Tiered, and Reserved back into the discussion as those were a more detailed version of what we were trying to do. - - We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. - - A few weeks before this, we as a group decided to use the term "Category" for normalized types and we also introduced a ChargeSubcategory column as the next level grouping. - - Update: In February/April 2024, it was decided that we would remove ChargeSubcategory for 1.0 GA. We may bring it back later once we have a better idea of what ChargeCategory breakdowns might be. - - Based on this Category/Subcategory pattern, we decided to break PricingModel into PricingCategory and PricingSubcategory, adding a more detailed breakdown of each category. - - Regarding "dynamic on-demand", this isn't possible given our current definitions (always-changing price vs. predetermined set price). - - As part of these discussions, we also discussed whether "On-Demand" was the right term. - - We discussed "Standard" as a replacement, but agreed "On-Demand" is more common and clear for the pricing model of pricing that is based on the published price for the billing account. (Note: Tiered pricing (aka volume-based discounts) are also predetermined and published, so they are also "On-Demand" by our definition.) - - We felt "Standard" was more clear as a differentiator from "Tiered" pricing. Another alternative was "Flat Rate". - - We also discussed whether to use "Commitment-Based" or "Discounted". - - If we use "Discounted", then any future discounting strategy could get rolled into a single column without the need to change values. - - The main downside of this is that, given how important commitment-based discounts are (and the fact that they are one of the primary reasons for adding this column), we felt it was important to call them out explicitly. - - Additionally, given different discount strategies will price things differently, it's also important that we distinguish the separate pricing models at the top level. - - We also didn't have any other clear examples that would fall into "Discounted" pricing that would be meaningfully grouped together in a way that practitioners would want to see together and not distinguished separately from their committed costs. - - We also discussed the term "Dynamic" and whether it was clear enough. - - During this, we discovered that "spot" is not a marketing term and is in fact a pricing construct for an always-changing price that a good or service can be immediately sold at. - - We discussed replacing "Dynamic" with "Spot", but agreed that "Dynamic" is more inclusive of other types of dynamic pricing models that may be introduced in the future and would likely be desirable to be grouped together. - - Given we cannot predict all pricing models that will be introduced in the future, we decided to also add "Other" in each subcategory. -- Unfortunately, we didn't think we had enough time to close PricingSubcategory, so we decided to hold that for after 1.0. +* Goal of the column is to enable practitioners to identify charges that have reduced prices vs. not. + * The most common question for this column is to identify commitment-based discounts and spot separate from on-demand. +* In 0.5, we didn't have enough time to close on how spot would be included: + * Someone mentioned that "spot" was a marketing term, so we tried to avoid it. + * We discussed values like "Preemptible" (confusing), "Interruptible" (not a pricing model), "Market-Based", "Variable", and "Dynamic". Ultimately, we agreed on "Dynamic". + * Then we questioned whether it "Dynamic" would be clear enough to practitioners who are looking for spot usage. +* In 1.0: + * We brought PricingModel back into discussion and had the same issues with "spot" being clearly understood as "Dynamic" so we decided to focus on other columns first. + * Over time, we got several requests to add a "PricingModel" column (that name explicitly), so we brought it back into discussion again. + * We agreed to add PricingModel as-is (with spot showing as "Dynamic"). +* While in PR, one member shared a link to IBM's documentation about how you're charged: https://cloud.ibm.com/docs/billing-usage?topic=billing-usage-charges + * IBM talks about Fixed, Metered, Tiered, and Reserved values. + * We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. + * The main concern about bringing these values in is that to get the on-demand costs, you'd have to look at 2 values, which makes it more complicated for practitioners. +* There was a poll with all members to determine if we should merge "Fixed" and "On-Demand" pricing options since they sounded near identical. + * 8 preferred merging and 3 preferred keeping them separate, so we decided to merge them. + * This was also discussed in the weekly member meeting, where people questioned using "On-Demand" for things that don't have a "pricing" model. + * We decided to use null when there is no price (SkuPriceId is null). + * As a note, multiple people have commented on nulls being more difficult for data analysis (since there's no clear meaning to why it's null). We did not have time to discuss this in the meeting, but it's something we should discuss in the future as it applies to all columns. + * The group also asked to add an "Other" option to account for any new pricing model that may come up in the future. +* Later, while still in PR, there was a concern about "dynamic on-demand pricing": + * This brought the IBM values of Fixed, Metered, Tiered, and Reserved back into the discussion as those were a more detailed version of what we were trying to do. + * We discussed this and decided that this was too detailed for PricingModel and would look at it in the future in another column. + * A few weeks before this, we as a group decided to use the term "Category" for normalized types and we also introduced a ChargeSubcategory column as the next level grouping. + * Based on this Category/Subcategory pattern, we decided to break PricingModel into PricingCategory and PricingSubcategory, adding a more detailed breakdown of each category. + * Regarding "dynamic on-demand", this isn't possible given our current definitions (always-changing price vs. predetermined set price). + * As part of these discussions, we also discussed whether "On-Demand" was the right term. + * We discussed "Standard" as a replacement, but agreed "On-Demand" is more common and clear for the pricing model of pricing that is based on the published price for the billing account. (Note: Tiered pricing (aka volume-based discounts) are also predetermined and published, so they are also "On-Demand" by our definition.) + * We felt "Standard" was more clear as a differentiator from "Tiered" pricing. Another alternative was "Flat Rate". + * We also discussed whether to use "Commitment-Based" or "Discounted". + * If we use "Discounted", then any future discounting strategy could get rolled into a single column without the need to change values. + * The main downside of this is that, given how important commitment-based discounts are (and the fact that they are one of the primary reasons for adding this column), we felt it was important to call them out explicitly. + * Additionally, given different discount strategies will price things differently, it's also important that we distinguish the separate pricing models at the top level. + * We also didn't have any other clear examples that would fall into "Discounted" pricing that would be meaningfully grouped together in a way that practitioners would want to see together and not distinguished separately from their committed costs. + * We also discussed the term "Dynamic" and whether it was clear enough. + * During this, we discovered that "spot" is not a marketing term and is in fact a pricing construct for an always-changing price that a good or service can be immediately sold at. + * We discussed replacing "Dynamic" with "Spot", but agreed that "Dynamic" is more inclusive of other types of dynamic pricing models that may be introduced in the future and would likely be desirable to be grouped together. + * Given we cannot predict all pricing models that will be introduced in the future, we decided to also add "Other" in each subcategory. +* Unfortunately, we didn't think we had enough time to close PricingSubcategory, so we decided to hold that for after 1.0. +* On April 3, 2024, we agreed to change "On-Demand" to "Standard" and "Commitment-Based" to "Committed". Open issues: diff --git a/supporting_content/columns/skupriceid.md b/supporting_content/columns/skupriceid.md index 159e02286..f3b3dffe6 100644 --- a/supporting_content/columns/skupriceid.md +++ b/supporting_content/columns/skupriceid.md @@ -1,4 +1,6 @@ -## Example provider mappings +# Column: SKU Price ID + +## Example provider mappings Current column mappings found in available data sets: @@ -9,7 +11,6 @@ Current column mappings found in available data sets: | GCP | BigQuery Billing Export | Not publically available, but can be derived from sku.id and price.tier_start_amount | | OCI | Cost Reports | Not available (no price level ID) | - ## Example scenarios for current provider data Current values observed in billing data for various scenarios: @@ -25,15 +26,27 @@ Current values observed in billing data for various scenarios: ### References -AWS - - -Azure - - -Big Query - - -OCI - - -Potato / Tomato v1 discussion: - -Potato / Tomato v2 discussion:\ +* AWS - +* Azure - +* Big Query - +* OCI - +* Potato / Tomato v1 discussion: +* Potato / Tomato v2 discussion:\ + +### Impacts of 1.0 ChargeCategory and ChargeClass cleanup + +The following table serves as the basis for reviewing the SkuPriceId spec, as well as price, cost, quantity metrics, etc., impacted by the ChargeCategory and ChargeClass columns cleanup + +| ChargeCategory | ChargeClass | perSku/bulk | SkuId | SkuPriceId | +|----------------|-------------|-----------------------------------|------------------|------------------| +| Usage | Regular | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | +| Usage | Correction | MAY be bulk | MAY be null | MAY be null | +| Purchase | Regular | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | +| Purchase | Correction | MAY be bulk | MAY be null | MAY be null | +| Credit | Regular | MAY be bulk | MAY be null | MAY be null | +| Credit | Correction | MAY be bulk | MAY be null | MAY be null | +| Adjustment | Regular | MAY be bulk | MAY be null | MAY be null | +| Adjustment | Correction | MAY be bulk | MAY be null | MAY be null | +| Tax | Regular | MUST be bulk | MUST be null | MUST be null | +| Tax | Correction | MUST be bulk | MUST be null | MUST be null | From 3038d4ac722c8b2184b2986485342e2e4ae11197 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Mon, 29 Apr 2024 14:50:01 +1000 Subject: [PATCH 48/65] Updated versioning/id approach to metadata (#415) Removed DataGeneratorVersion Added SchemaId under schema section Moved ProviderTagPrefixes to live under the column definition of the Schema --------- Signed-off-by: Mike Fuller Co-authored-by: rileyjenk Co-authored-by: Joaquin --- .../data_generator/data_generator.mdpp | 2 - .../data_generator/datageneratorversion.md | 17 ---- .../column_definition/column_definition.mdpp | 5 +- .../column_definition/providertagprefixes.md} | 2 +- specification/metadata/schema/schema.mdpp | 1 + specification/metadata/schema/schemaid.md | 17 ++++ supporting_content/metadata/metadata.md | 83 ++++++++++--------- 7 files changed, 65 insertions(+), 62 deletions(-) delete mode 100644 specification/metadata/data_generator/datageneratorversion.md rename specification/metadata/{data_generator/providertagprefix.md => schema/column_definition/providertagprefixes.md} (57%) create mode 100644 specification/metadata/schema/schemaid.md diff --git a/specification/metadata/data_generator/data_generator.mdpp b/specification/metadata/data_generator/data_generator.mdpp index 89a05a373..80b36aa5c 100644 --- a/specification/metadata/data_generator/data_generator.mdpp +++ b/specification/metadata/data_generator/data_generator.mdpp @@ -3,5 +3,3 @@ The FOCUS metadata about the generator of the FOCUS data. !INCLUDE "datagenerator.md",1 -!INCLUDE "datageneratorversion.md",1 -!INCLUDE "providertagprefix.md",1 diff --git a/specification/metadata/data_generator/datageneratorversion.md b/specification/metadata/data_generator/datageneratorversion.md deleted file mode 100644 index 1d3edf671..000000000 --- a/specification/metadata/data_generator/datageneratorversion.md +++ /dev/null @@ -1,17 +0,0 @@ -# Data Generator Version - -A version specific to the data generator for providers which support multiple FOCUS datasets with different provider columns, or for providers who release multiple versions of their generated datasets between FOCUS Versions. - -The DataGeneratorVersion MUST be provided in the metadata, when multiple datasets using the same FOCUS version are provided with different provider columns. DataGeneratorVersion MUST be of type String and MUST NOT contain null values. The DataGeneratorVersion is RECOMMENDED to use semantic versioning. - -## Metadata ID - -DataGeneratorVersion - -## Metadata Name - -Data Generator Version - -## Introduced (version) - -1.0 diff --git a/specification/metadata/schema/column_definition/column_definition.mdpp b/specification/metadata/schema/column_definition/column_definition.mdpp index 668103b04..75971504e 100644 --- a/specification/metadata/schema/column_definition/column_definition.mdpp +++ b/specification/metadata/schema/column_definition/column_definition.mdpp @@ -4,7 +4,8 @@ The FOCUS metadata schema column definition provides a list of the columns prese !INCLUDE "columnname.md",1 !INCLUDE "datatype.md",1 -!INCLUDE "stringencoding.md",1 -!INCLUDE "stringmaxlength.md",1 !INCLUDE "numericprecision.md",1 !INCLUDE "numberscale.md",1 +!INCLUDE "providertagprefixes.md",1 +!INCLUDE "stringencoding.md",1 +!INCLUDE "stringmaxlength.md",1 diff --git a/specification/metadata/data_generator/providertagprefix.md b/specification/metadata/schema/column_definition/providertagprefixes.md similarity index 57% rename from specification/metadata/data_generator/providertagprefix.md rename to specification/metadata/schema/column_definition/providertagprefixes.md index 61b98e777..d6267ffae 100644 --- a/specification/metadata/data_generator/providertagprefix.md +++ b/specification/metadata/schema/column_definition/providertagprefixes.md @@ -2,7 +2,7 @@ The Provider Tag Prefixes defines the list of prefixes used in the tag name of provider-defined [tags](#tags). This metadata is useful for the consumer to identify which tags are provider-defined vs user-defined. -The ProviderTagPrefixes SHOULD be provided when the provider supports provider-defined tags. The ProviderTagPrefix MUST be of type Array of Strings. The ProviderTagPrefixes SHOULD be easily associated with the provider who generated the FOCUS dataset. +The ProviderTagPrefixes MUST be provided when ColumnName is equal to Tags. The ProviderTagPrefix MUST be of type Array of Strings. The ProviderTagPrefixes SHOULD be easily associated with the provider who generated the FOCUS dataset. ## Metadata ID diff --git a/specification/metadata/schema/schema.mdpp b/specification/metadata/schema/schema.mdpp index b4d9d72ac..b27448e13 100644 --- a/specification/metadata/schema/schema.mdpp +++ b/specification/metadata/schema/schema.mdpp @@ -2,6 +2,7 @@ Each FOCUS dataset must have a metadata about the schema associated with it. The schema metadata provides information about the structure of the data provided. +!INCLUDE "schemaid.md",1 !INCLUDE "creationdate.md",1 !INCLUDE "focusversion.md",1 !INCLUDE "column_definition/column_definition.mdpp",1 diff --git a/specification/metadata/schema/schemaid.md b/specification/metadata/schema/schemaid.md new file mode 100644 index 000000000..d55872250 --- /dev/null +++ b/specification/metadata/schema/schemaid.md @@ -0,0 +1,17 @@ +# Schema ID + +The Schema ID provides the reference item to associate which Schema was used for the generation of a FOCUS Dataset. + +The SchemaId MUST be present in the metadata. The SchemaId MUST be of String. It is RECOMMENDED for SchemaId to be a Universally Unique Identifier (UUID) or [SemVer](https://semver.org) version. + +## Metadata ID + +SchemaId + +## Metadata Name + +Schema ID + +## Introduced (version) + +1.0 diff --git a/supporting_content/metadata/metadata.md b/supporting_content/metadata/metadata.md index e6406c6b9..9ba2b1101 100644 --- a/supporting_content/metadata/metadata.md +++ b/supporting_content/metadata/metadata.md @@ -14,9 +14,7 @@ In this example the billing data generator's FOCUS metadata API is queried for t #### Response ``` { - "DataGenerator": "awesome_corp", - "DataGeneratorVersion": "1.0.1", - "ProviderTagPrefixes": ["awecorp", "ac"] + "DataGenerator": "awesome_corp" }` ``` @@ -69,43 +67,48 @@ In this example the billing data generator's FOCUS metadata API is queried for t ``` { "FOCUS_version": "1.0", - "name": "my original schema", - "CreationDate": "2024-01-01T12:01:03.083z" + "name": "my original schema", + "CreationDate": "2024-01-01T12:01:03.083z" "ColumnDefinition": [ - { - ColumnName: "BillingAccountId", - DataType: "STRING" - StringMaxLength: 64, - StringEncoding: "UTF-8" - }, - { - ColumnName: "BillingAccountName", - DataType: "STRING" - StringMaxLength: 64, - StringEncoding: "UTF-8" - }, - { - ColumnName: "ChargePeriodStart", - DataType: "DATETIME" - }, - { - ColumnName: "ChargePeriodEnd", - DataType: "DATETIME" - }, - { - ColumnName: "BilledCost", - DataType: "DECIMAL", - NumericPrecision: 20, - NumberScale: 10 - }, - { - ColumnName: "EffecitiveCost", - DataType: "DECIMAL", - NumericPrecision: 20, - NumberScale: 10 - }, - ] -}` + { + "ColumnName": "BillingAccountId", + "DataType": "STRING", + "StringMaxLength: 64, + "StringEncoding: "UTF-8" + }, + { + "ColumnName: "BillingAccountName", + "DataType: "STRING" + "StringMaxLength: 64, + "StringEncoding: "UTF-8" + }, + { + "ColumnName: "ChargePeriodStart", + "DataType: "DATETIME" + }, + { + "ColumnName: "ChargePeriodEnd", + "DataType: "DATETIME" + }, + { + "ColumnName: "BilledCost", + "DataType: "DECIMAL", + "NumericPrecision: 20, + "NumberScale: 10 + }, + { + "ColumnName: "EffecitiveCost", + "DataType: "DECIMAL", + "NumericPrecision: 20, + "NumberScale: 10 + }, + { + "ColumnName": "Tags", + "DataType": "JSON", + "ProviderTagPrefixes": ["awecorp", "ac"] + } + ] +} ``` ## Example Schema Reference Metadata @@ -124,4 +127,4 @@ In this example, when the provider returns the FOCUS data they include in the re ... ] } -``` \ No newline at end of file +``` From 6cbbad11334a357e9de97ef6ba091af197b09823 Mon Sep 17 00:00:00 2001 From: Udam Dewaraja Date: Mon, 6 May 2024 15:05:57 -0700 Subject: [PATCH 49/65] 424: Description updates on when to exclude to avoid double counting List/Contracted (#428) Issue #424: Add warning about the risk of double-counting in List/Contracted Cost columns. --------- Co-authored-by: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Co-authored-by: Joaquin Co-authored-by: Michael Flanakin --- specification/columns/contractedcost.md | 2 ++ specification/columns/listcost.md | 4 +++- supporting_content/columns/contractedcost.md | 6 ++++++ supporting_content/columns/listcost.md | 8 ++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/specification/columns/contractedcost.md b/specification/columns/contractedcost.md index 33b56f225..34bc4fe35 100644 --- a/specification/columns/contractedcost.md +++ b/specification/columns/contractedcost.md @@ -2,6 +2,8 @@ Contracted Cost represents the cost calculated by multiplying [*contracted unit price*](#glossary:contracted-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). Contracted Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on negotiation activities, by comparing it with [List Cost](#listcost). If negotiated discounts are not applicable, the Contracted Cost defaults to the List Cost. +**Important:** When aggregating Contracted Cost for savings calculations, it's important to exclude either one-time or recurring charges ([ChargeCategory](#chargecategory)"Purchase") that are paid to cover future eligible charges or the covered charges themselves. This exclusion helps prevent double counting of these charges in the aggregation. Which set of charges to exclude depends on whether cost are aggregated on a billed basis (exclude covered charges) or accrual basis (exclude Purchases for future charges). For instance, charges categorized as [ChargeCategory](#chargecategory) "Purchase" and their related [ChargeCategory](#chargecategory) "Tax" charges for a [Commitment-Based Discount](#glossary:commitment-based-discount) might be excluded from an accrual basis cost aggregation of Contracted Cost. This is because the "Usage" and "Tax" charge records provided during the term of the commitment discount already specify the Contracted Cost. + The ContractedCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ContractedUnitPrice](#contractedunitprice) is present and not null, multiplying the ContractedUnitPrice by PricingQuantity MUST produce the ContractedCost, except in cases of [ChargeClass](#chargeclass) "Correction", which may address PricingQuantity or any cost discrepancies independently. In cases where the ContractedUnitPrice is present and null, the following applies: diff --git a/specification/columns/listcost.md b/specification/columns/listcost.md index a9ec757c2..e5d296e3a 100644 --- a/specification/columns/listcost.md +++ b/specification/columns/listcost.md @@ -1,6 +1,8 @@ # List Cost -List Cost represents the cost calculated by multiplying the [*list unit price*](#glossary:list-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). List Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on various rate optimization activities, by comparing it with [Billed Cost](#billedcost) and [Effective Cost](#effectivecost). +List Cost represents the cost calculated by multiplying the [*list unit price*](#glossary:list-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). List Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on various rate optimization activities, by comparing it with [Contracted Cost](#contractedcost), [Billed Cost](#billedcost) and [Effective Cost](#effectivecost). + +**Important:** When aggregating ListCost for savings calculations, it's important to exclude either one-time or recurring charges ([ChargeCategory](#chargecategory)"Purchase") that are paid to cover future eligible charges or the covered charges themselves. This exclusion helps prevent double counting of these charges in the aggregation. Which set of charges to exclude depends on whether cost are aggregated on a billed basis (exclude covered charges) or accrual basis (exclude Purchases for future charges). For instance, charges categorized as [ChargeCategory](#chargecategory) "Purchase" and their related [ChargeCategory](#chargecategory) "Tax" charges for a [Commitment-Based Discount](#glossary:commitment-based-discount) might be excluded from an accrual basis cost aggregation of List Cost. This is because the "Usage" and "Tax" charge records provided during the term of the commitment discount already specify the List Cost. The ListCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ListUnitPrice](#listunitprice) is present and not null, multiplying the ListUnitPrice by PricingQuantity MUST produce the ListCost, except in cases of [ChargeClass](#chargeclass) "Correction", which may address PricingQuantity or any cost discrepancies independently. diff --git a/supporting_content/columns/contractedcost.md b/supporting_content/columns/contractedcost.md index 8c23df88a..e61c53d0c 100644 --- a/supporting_content/columns/contractedcost.md +++ b/supporting_content/columns/contractedcost.md @@ -36,6 +36,12 @@ Current column mappings found in available data sets: ## Discussion / Scratch space +* April 20, 2024 update: Double counting issue was discussed in github issue [#424](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/issues/424). Options discussed were: + * Enhance the description about excluding ListCost and ContractedCost from purchases and related charges (e.g. Tax for the purchase) from aggregations related to savings calculations to avoid double counting + * Update the description to require purchases that cover future eligible charges to have a ContractedCost of 0$ + * Update the description to require the covered rows to have a ContractedCost of 0$ +* Based on discussions, we determined that it was useful at a row-level to have the ContractedCost specified but call out the need to exclude the purchase or usage rows to avoid double counting when aggregated. For accrual basis analysis, the purchase might be excluded. For cash-basis analysis, the usage charges may be excluded. + ### GCP column mappings * **cost** - The cost of the usage before any credits, to a precision of up to six decimal places. To get the total cost including credits, any credits.amount should be added to cost. diff --git a/supporting_content/columns/listcost.md b/supporting_content/columns/listcost.md index d3c2b4235..e7c9c7c4f 100644 --- a/supporting_content/columns/listcost.md +++ b/supporting_content/columns/listcost.md @@ -47,3 +47,11 @@ Current column mappings found in available data sets: ### Current data sources * Even though some major CSPs provide candidate columns for mapping to ListCost within their billing data, it is advisable to rely on multiplying the predetermined values in the FOCUS columns ListUnitPrice and PricingQuantity. This approach ensures more consistent and reliable results. + +### Avoid double counting + +* 4/20/2024 Double counting issue was discussed in github issue [#424](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/issues/424). Options discussed were: + * Enhance the description about excluding ListCost and ContractedCost from purchases and related charges (e.g. Tax for the purchase) from aggregations related to savings calculations to avoid double counting + * Update the description to require purchases that cover future eligible charges to have a ListCost of 0$ + * Update the description to require the covered rows to have a ListCost of 0$ +* Based on discussions, we determined that it was useful at a row-level to have the ListCost specified but call out the need to exclude the purchase or usage rows to avoid double counting when aggregated. For accrual basis analysis, the purchase might be excluded. For cash-basis analysis, the usage charges may be excluded. \ No newline at end of file From 54d9de7ef25673492a0985be1f47572185c91b77 Mon Sep 17 00:00:00 2001 From: kotzenjh Date: Tue, 7 May 2024 00:26:41 +0100 Subject: [PATCH 50/65] 426-consistency-review-chargecategory-definition-and-description-review (#433) Parts of the initial definition are no longer applicable since changes to the allowed values list (credit is no longer part of the adjustment category but a separate category) and the introduction of additional columns. It has beeb raised for example, how this column would be used for separate charges that may require special handling from regular usage. --------- Co-authored-by: Michael Flanakin Co-authored-by: Udam Dewaraja --- specification/columns/chargecategory.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/columns/chargecategory.md b/specification/columns/chargecategory.md index bb51ffbe5..c0fa80162 100644 --- a/specification/columns/chargecategory.md +++ b/specification/columns/chargecategory.md @@ -1,6 +1,6 @@ # Charge Category -A Charge Category is the highest level classification for the type of charge that the billing row represents. The Charge Category is commonly used to identify prepaid purchases separately from usage-based charges or to separate charges that may require special handling from regular usage. +Charge Category represents the highest-level classification of a charge based on the nature of how it is billed. Charge Category is commonly used to identify and distinguish between types of charges that may require different handling. The ChargeCategory column MUST be present in the billing data and MUST NOT be null. This column is of type String and MUST be one of the allowed values. @@ -14,7 +14,7 @@ Charge Category ## Description -Indicates whether the row represents an upfront or recurring fee, cost of usage that already occurred, an after-the-fact *adjustment* (e.g., credits), or taxes. +Represents the highest-level classification of a charge based on the nature of how it is billed. ## Content Constraints From 76dd00a930d20c6accbac4ca1f2de1110fc22bcf Mon Sep 17 00:00:00 2001 From: Irena Jurica Date: Tue, 7 May 2024 03:14:04 +0200 Subject: [PATCH 51/65] FOCUS #430: EffectiveCost spec change - addressing purchases paid to cover future eligible charges (#431) EffectiveCost spec change - addressing purchases paid to cover future eligible charges --------- Co-authored-by: Michael Flanakin Co-authored-by: Udam Dewaraja Co-authored-by: Joaquin --- CHANGELOG.md | 1 + specification/columns/effectivecost.md | 6 +++--- specification/glossary.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aef0381c2..076acbe5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Column is conditional and only required when the provider supports commitment discounts. - `EffectiveCost` column updates: - Clarified that effective cost does not mix or "blend" costs across multiple charges. + - Specified that in the case of a purchase charge paid to cover future eligible charges, the Effective Cost is set to 0. - `ListUnitPrice` column updates: - Column is conditional and only required when the provider publishes a price list that excludes discounts. - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". diff --git a/specification/columns/effectivecost.md b/specification/columns/effectivecost.md index 4ebe952b6..05ca41001 100644 --- a/specification/columns/effectivecost.md +++ b/specification/columns/effectivecost.md @@ -1,13 +1,13 @@ # Effective Cost -Effective Cost represents a cost inclusive of the impacts of all reduced rates and discounts, augmented with the [*amortization*](#glossary:amortization) of relevant purchases (one-time or recurring) paid to cover future eligible charges. The *amortized* portion included should be proportional to the [Pricing Quantity](#pricingquantity) and the time granularity of the data. Effective Cost does not mix or "blend" costs across multiple charges of the same service. This cost is denominated in the [Billing Currency](#billingcurrency). The Effective Cost is commonly utilized to track and analyze spending trends. +Effective Cost represents the [*amortized*](#glossary:amortization) cost of the [*charge*](#glossary:charge) after applying all reduced rates, discounts, and the applicable portion of relevant, prepaid purchases (one-time or recurring) that covered this charge. The *amortized* portion included should be proportional to the [Pricing Quantity](#pricingquantity) and the time granularity of the data. Since amortization breaks down and spreads the cost of a prepaid purchase, to subsequent eligible charges, the Effective Cost of the original prepaid charge is set to 0. Effective Cost does not mix or "blend" costs across multiple charges of the same service. This cost is denominated in the [Billing Currency](#billingcurrency). The Effective Cost is commonly utilized to track and analyze spending trends. This column resolves two challenges that are faced by practitioners: 1. Practitioners need to *amortize* relevant purchases, such as upfront fees, throughout the *commitment* and distribute them to the appropriate reporting groups (e.g. [*tags*](#glossary:tag), [*resources*](#glossary:resource)). 2. Many [*commitment-based discount*](#glossary:commitment-based-discount) constructs include a recurring expense for the *commitment* for every [*billing period*](#glossary:billing-period) and must distribute this cost to the *resources* using the *commitment*. This forces reconciliation between the initial *commitment* [*row*](#glossary:row) per period and the actual usage *rows*. -The EffectiveCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. The aggregated EffectiveCost for a billing period MAY NOT match the charge received on the invoice for the same *billing period*. +The EffectiveCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. EffectiveCost MUST be 0 when ChargeCategory is "Purchase" and the purchase is intended to cover future eligible charges. The aggregated EffectiveCost for a billing period may not match the charge received on the invoice for the same *billing period*. In cases where the [ChargeCategory](#chargecategory) is not "Usage" or "Purchase", the following applies: @@ -24,7 +24,7 @@ Effective Cost ## Description -Cost inclusive of the impacts of all reduced rates and discounts, augmented with the *amortization* of relevant purchases (one-time or recurring) paid to cover future eligible *charges*. +The *amortized* cost of the *charge* after applying all reduced rates, discounts, and the applicable portion of relevant, prepaid purchases (one-time or recurring) that covered this charge. ### Concerning Granularity and Distribution of Recurring Fee diff --git a/specification/glossary.md b/specification/glossary.md index 2aa21ba2e..7e45a5db4 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -58,7 +58,7 @@ A specification-defined categorical attribute that provides context or categoriz Effective Cost -Cost inclusive of the impacts of all reduced rates and discounts, augmented with the amortization of relevant purchases (one-time or recurring) paid to cover future eligible charges. +The amortized cost of the charge after applying all reduced rates, discounts, and the applicable portion of relevant, prepaid purchases (one-time or recurring) that covered this charge. Exclusive Bound From 51a3b99b653ab74a86e6f0b5afc8961cede20ed3 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Tue, 7 May 2024 14:26:51 +1000 Subject: [PATCH 52/65] Fix broken builds reported in #438 (#439) In order to unbreak the github actions pipeline, adding temporary fix which will allow the pip install to apply to the system python on the container. This is low risk as the python install is only active for the life of the build. If we want to avoid this we need to do further testing on using a venv for the spec creation. But this PR gets the pipeline unblocked for the pending 1.0 release. --------- Signed-off-by: Mike Fuller --- .github/workflows/candidate_release.yml | 62 +++++++++++------------ .github/workflows/main.yml | 62 +++++++++++------------ .github/workflows/working_draft.yml | 66 ++++++++++++------------- requirements.txt | 2 +- 4 files changed, 96 insertions(+), 96 deletions(-) diff --git a/.github/workflows/candidate_release.yml b/.github/workflows/candidate_release.yml index 26f1fb644..34d6f975d 100644 --- a/.github/workflows/candidate_release.yml +++ b/.github/workflows/candidate_release.yml @@ -2,36 +2,36 @@ name: generate_candidate_release_spec on: push: branches: - - 'candidate_release' + - "candidate_release" jobs: - # The job that will use the container image you just pushed to ghcr.io - gen_pdf: - runs-on: ubuntu-20.04 - container: - image: pandoc/extra:latest-ubuntu - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install prequirements - shell: bash - run: | - /usr/bin/apt-get -y update - wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb - DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y make - DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y -f ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb - /usr/bin/pip3 install -r requirements.txt - - name: Build PDF - shell: bash - working-directory: ./specification - run: | - make STYLE=candidate_release - - name: Upload Spec - uses: actions/upload-artifact@v3.1.2 - with: - name: FOCUS_specification - path: | - specification/spec.html - specification/spec.pdf - specification/images/* - specification/styles/* + # The job that will use the container image you just pushed to ghcr.io + gen_pdf: + runs-on: ubuntu-20.04 + container: + image: pandoc/extra:latest-ubuntu + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Install prequirements + shell: bash + run: | + /usr/bin/apt-get -y update + wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb + DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y make + DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y -f ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb + /usr/bin/pip3 install --break-system-packages -r requirements.txt + - name: Build PDF + shell: bash + working-directory: ./specification + run: | + make STYLE=candidate_release + - name: Upload Spec + uses: actions/upload-artifact@v3.1.2 + with: + name: FOCUS_specification + path: | + specification/spec.html + specification/spec.pdf + specification/images/* + specification/styles/* diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c58f4281..3de84c958 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,36 +2,36 @@ name: generate_publication_spec on: push: branches: - - 'main' + - "main" jobs: - # The job that will use the container image you just pushed to ghcr.io - gen_pdf: - runs-on: ubuntu-20.04 - container: - image: pandoc/extra:latest-ubuntu - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install prequirements - shell: bash - run: | - /usr/bin/apt-get -y update - wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb - DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y make - DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y -f ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb - /usr/bin/pip3 install -r requirements.txt - - name: Build PDF - shell: bash - working-directory: ./specification - run: | - make STYLE=main - - name: Upload Spec - uses: actions/upload-artifact@v3.1.2 - with: - name: FOCUS_specification - path: | - specification/spec.html - specification/spec.pdf - specification/images/* - specification/styles/* + # The job that will use the container image you just pushed to ghcr.io + gen_pdf: + runs-on: ubuntu-20.04 + container: + image: pandoc/extra:latest-ubuntu + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Install prequirements + shell: bash + run: | + /usr/bin/apt-get -y update + wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb + DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y make + DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y -f ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb + /usr/bin/pip3 install --break-system-packages -r requirements.txt + - name: Build PDF + shell: bash + working-directory: ./specification + run: | + make STYLE=main + - name: Upload Spec + uses: actions/upload-artifact@v3.1.2 + with: + name: FOCUS_specification + path: | + specification/spec.html + specification/spec.pdf + specification/images/* + specification/styles/* diff --git a/.github/workflows/working_draft.yml b/.github/workflows/working_draft.yml index d02255d8d..0e446d759 100644 --- a/.github/workflows/working_draft.yml +++ b/.github/workflows/working_draft.yml @@ -2,38 +2,38 @@ name: generate_draft_spec on: push: branches: - - '*' - - '!main' - - '!candidate_release' + - "*" + - "!main" + - "!candidate_release" jobs: - # The job that will use the container image you just pushed to ghcr.io - gen_pdf: - runs-on: ubuntu-20.04 - container: - image: pandoc/extra:latest-ubuntu - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install prequirements - shell: bash - run: | - /usr/bin/apt-get -y update - wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb - DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y make - DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y -f ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb - /usr/bin/pip3 install -r requirements.txt - - name: Build PDF - shell: bash - working-directory: ./specification - run: | - make STYLE=working_draft - - name: Upload Spec - uses: actions/upload-artifact@v3.1.2 - with: - name: FOCUS_specification - path: | - specification/spec.html - specification/spec.pdf - specification/images/* - specification/styles/* + # The job that will use the container image you just pushed to ghcr.io + gen_pdf: + runs-on: ubuntu-20.04 + container: + image: pandoc/extra:latest-ubuntu + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Install prequirements + shell: bash + run: | + /usr/bin/apt-get -y update + wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb + DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y make + DEBIAN_FRONTEND=noninteractive /usr/bin/apt install -y -f ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb + /usr/bin/pip3 install --break-system-packages -r requirements.txt + - name: Build PDF + shell: bash + working-directory: ./specification + run: | + make STYLE=working_draft + - name: Upload Spec + uses: actions/upload-artifact@v3.1.2 + with: + name: FOCUS_specification + path: | + specification/spec.html + specification/spec.pdf + specification/images/* + specification/styles/* diff --git a/requirements.txt b/requirements.txt index 7a6ec4b91..5b023374b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ watchdog==3.0.0 -pymarkdownlnt==0.9.11 +pymarkdownlnt==0.9.12 From 5467477755b8cb3990cb0350ffa43f0246c1fab1 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Fri, 10 May 2024 07:20:18 +1000 Subject: [PATCH 53/65] Rename branch candidate_release to candidate_recommendation (#450) Update branch 'candidate_release' to 'candidate_recommendation' as per our foundation operational procedures Signed-off-by: Mike Fuller --- .github/workflows/candidate_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/candidate_release.yml b/.github/workflows/candidate_release.yml index 34d6f975d..cb3e69939 100644 --- a/.github/workflows/candidate_release.yml +++ b/.github/workflows/candidate_release.yml @@ -2,7 +2,7 @@ name: generate_candidate_release_spec on: push: branches: - - "candidate_release" + - "candidate_recommendation" jobs: # The job that will use the container image you just pushed to ghcr.io From 058623a8e4c70c3f7192e1ea3c71f2e78c1ac0a1 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Fri, 10 May 2024 09:05:41 +1000 Subject: [PATCH 54/65] Correction of term sponsored with supported (#447) The FinOps Foundation is a supporter of the FOCUS Project. The FinOps Foundation would like the phrase "This project is sponsored by the FinOps Foundation" be updated to "This project is supported by the FinOps Foundation" Signed-off-by: Mike Fuller --- specification/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/overview.md b/specification/overview.md index 1a0cc3f45..6257c1806 100644 --- a/specification/overview.md +++ b/specification/overview.md @@ -8,7 +8,7 @@ The FOCUS specification's schema definition and FinOps-aligned terminology provi ## Background and History -This project is sponsored by the [FinOps Foundation][FODO]. This work initially started under the Open Billing working group under the FinOps Foundation. The decision was made in Jan 2023 to begin to migrate the work to a newly formed project under the Linux Foundation called the FinOps Open Cost and Usage Specification (FOCUS) to better support the creation of a specification. +This project is supported by the [FinOps Foundation][FODO]. This work initially started under the Open Billing working group under the FinOps Foundation. The decision was made in Jan 2023 to begin to migrate the work to a newly formed project under the Linux Foundation called the FinOps Open Cost and Usage Specification (FOCUS) to better support the creation of a specification. ## Intended Audience From 2776a8f7dea27121988c8f85c874033712c34e1e Mon Sep 17 00:00:00 2001 From: Andrew Qu <115758900+aqu-erp@users.noreply.github.com> Date: Thu, 9 May 2024 16:21:31 -0700 Subject: [PATCH 55/65] #409 Path 1 - Usage Unit/Quantity restricted to usage charges and renamed to Consumed Unit/Quantity (#418) PR 1 of 2 Based on the conversation today, it was agreed that (non-pricing) quantities pertaining to purchase or SaaS charges need additional development. The changes in this PR to UsageQuantity and UsageUnit definitions intend to: - Rename the column to Consumed Quantity and ConsumedUnit - Narrow the application of UsageQuantity and UsageUnit to usage charges - Retain flexibility to revisit quantities related to purchase charges - Mitigate unclean or irrelevant values in the interim and allow future additive changes --------- Co-authored-by: Udam Dewaraja Co-authored-by: Joaquin --- CHANGELOG.md | 16 +++++----- specification/columns/columns.mdpp | 4 +-- specification/columns/consumedquantity.md | 32 +++++++++++++++++++ specification/columns/consumedunit.md | 31 ++++++++++++++++++ specification/columns/pricingquantity.md | 4 +-- specification/columns/pricingunit.md | 4 +-- specification/columns/usagequantity.md | 32 ------------------- specification/columns/usageunit.md | 31 ------------------ specification/glossary.md | 2 +- .../columns/consumedquantity.md | 18 +++++++++++ .../columns/{usageunit.md => consumedunit.md} | 4 ++- supporting_content/columns/usagequantity.md | 11 ------- 12 files changed, 99 insertions(+), 90 deletions(-) create mode 100644 specification/columns/consumedquantity.md create mode 100644 specification/columns/consumedunit.md delete mode 100644 specification/columns/usagequantity.md delete mode 100644 specification/columns/usageunit.md create mode 100644 supporting_content/columns/consumedquantity.md rename supporting_content/columns/{usageunit.md => consumedunit.md} (64%) delete mode 100644 supporting_content/columns/usagequantity.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 076acbe5a..7f081ba97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Column is conditional and only required when the provider supports commitment discounts. - `CommitmentDiscountType` column updates: - Column is conditional and only required when the provider supports commitment discounts. +- `ConsumedQuantity` column updates: + - Column renamed from UsageQuantity. It is now limited to ChargeType "Usage" rows. + - Column is conditional and only required when the provider supports the measurement of usage. + - Column must not be null when `ChargeCategory` is "Usage" and `ChargeClass` is not "Correction". +- `ConsumedUnit` column updates: + - Column renamed from UsageUnit. It is now limited to ChargeType "Usage" rows. + - Column is conditional and only required when the provider supports the measurement of usage. + - Column must not be null when `ChargeCategory` is "Usage" and `ChargeClass` is not "Correction". - `EffectiveCost` column updates: - Clarified that effective cost does not mix or "blend" costs across multiple charges. - Specified that in the case of a purchase charge paid to cover future eligible charges, the Effective Cost is set to 0. @@ -75,14 +83,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `Tags` column updates: - Column is conditional and only required when the provider supports setting user- or provider-defined tags. - Tag keys that cannot have a value must use a boolean `true` as the tag value. -- `UsageQuantity` column updates: - - Column is conditional and only required when the provider supports the measurement of usage. - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". - - Must be null when `ChargeCategory` is "Tax". -- `UsageUnit` column updates: - - Column is conditional and only required when the provider supports the measurement of usage. - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". - - Must be null when `ChargeCategory` is "Tax". **Fixed:** diff --git a/specification/columns/columns.mdpp b/specification/columns/columns.mdpp index 14686004d..423c7af43 100644 --- a/specification/columns/columns.mdpp +++ b/specification/columns/columns.mdpp @@ -20,6 +20,8 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "commitmentdiscountname.md",1 !INCLUDE "commitmentdiscounttype.md",1 !INCLUDE "commitmentdiscountstatus.md",1 +!INCLUDE "consumedquantity.md",1 +!INCLUDE "consumedunit.md",1 !INCLUDE "contractedcost.md",1 !INCLUDE "contractedunitprice.md",1 !INCLUDE "effectivecost.md",1 @@ -43,7 +45,5 @@ The FOCUS specification defines a group of columns that provide qualitative valu !INCLUDE "subaccountid.md",1 !INCLUDE "subaccountname.md",1 !INCLUDE "tags.md",1 -!INCLUDE "usagequantity.md",1 -!INCLUDE "usageunit.md",1 [FODOFC]: https://www.finops.org/framework/capabilities/ diff --git a/specification/columns/consumedquantity.md b/specification/columns/consumedquantity.md new file mode 100644 index 000000000..41f3763fb --- /dev/null +++ b/specification/columns/consumedquantity.md @@ -0,0 +1,32 @@ +# Consumed Quantity + +The Consumed Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used, based on the [Consumed Unit](#consumedunit). Consumed Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)) and focuses on *resource* and *service* consumption, not pricing and cost. + +ConsumedQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" and [ChargeClass](#chargeclass) is not "Correction". This column MUST be null for other ChargeCategory values. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". + +## Column ID + +ConsumedQuantity + +## Display Name + +Consumed Quantity + +## Description + +The volume of a given SKU associated with a *resource* or *service* used, based on the Consumed Unit. + +## Content constraints + +| Constraint | Value | +|:----------------|:--------------| +| Column type | Metric | +| Feature level | Conditional | +| Allows nulls | True | +| Data type | Decimal | +| Value format | [Numeric Format](#numericformat) | +| Number range | Any valid decimal value | + +## Introduced (version) + +1.0 diff --git a/specification/columns/consumedunit.md b/specification/columns/consumedunit.md new file mode 100644 index 000000000..0c9788cdc --- /dev/null +++ b/specification/columns/consumedunit.md @@ -0,0 +1,31 @@ +# Consumed Unit + +The Consumed Unit represents a provider-specified measurement unit indicating how a provider measures usage of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service). Consumed Unit complements the [Consumed Quantity](#consumedquantity) metric. It is often listed at a finer granularity or over a different time interval when compared to [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. + +The ConsumedUnit column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. ConsumedUnit MUST NOT be null if [ChargeCategory](#chargecategory) is "Usage" and [ChargeClass](#chargeclass) is not "Correction". This column MUST be null for other ChargeCategory values. Units of measure used in ConsumedUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The ConsumedUnit column MUST NOT be used to determine values related to any pricing or cost metrics. + +## Column ID + +ConsumedeUnit + +## Display Name + +Consumed Unit + +## Description + +Provider-specified measurement unit indicating how a provider measures usage of a given SKU associated with a *resource* or *service*. + +## Content constraints + +| Constraint | Value | +|:----------------|:----------------| +| Column type | Metric | +| Feature level | Conditional | +| Allows nulls | True | +| Data type | String | +| Value format | [Unit Format](#unitformat) recommended | + +## Introduced (version) + +1.0 diff --git a/specification/columns/pricingquantity.md b/specification/columns/pricingquantity.md index cd1761fc0..f695c833c 100644 --- a/specification/columns/pricingquantity.md +++ b/specification/columns/pricingquantity.md @@ -1,8 +1,8 @@ # Pricing Quantity -The Pricing Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Pricing Unit](#pricingunit). Distinct from [Usage Quantity](#usagequantity) (complementary to [Usage Unit](#usageunit)), it focuses on pricing and cost, not *resource* and *service* consumption. +The Pricing Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Pricing Unit](#pricingunit). Distinct from [Consumed Quantity](#consumedquantity) (complementary to [Consumed Unit](#consumedunit)), it focuses on pricing and cost, not *resource* and *service* consumption. -The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric, except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. +The PricingQuantity column MUST be present in the billing data. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When unit prices are not null, multiplying PricingQuantity by a unit price MUST produce a result equal to the corresponding cost metric, except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. ## Column ID diff --git a/specification/columns/pricingunit.md b/specification/columns/pricingunit.md index bfc88ce4a..5e283e6fa 100644 --- a/specification/columns/pricingunit.md +++ b/specification/columns/pricingunit.md @@ -1,8 +1,8 @@ # Pricing Unit -The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how the provider rates measured usage and purchase quantities after applying pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Usage Unit](#usageunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. +The Pricing Unit represents a provider-specified measurement unit for determining unit prices, indicating how the provider rates measured usage and purchase quantities after applying pricing rules like [*block pricing*](#glossary:block-pricing). Common examples include the number of hours for compute appliance runtime (e.g. `Hours`), gigabyte-hours for a storage appliance (e.g., `GB-Hours`), or an accumulated count of requests for a network appliance or API service (e.g., `1000 Requests`). Pricing Unit complements the [Pricing Quantity](#pricingquantity) metric. Distinct from the [Consumed Unit](#Consumedunit), it focuses on pricing and cost, not [*resource*](#glossary:resource) and [*service*](#glossary:service) consumption, often at a coarser granularity. -The PricingUnit column MUST be present in the billing data. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. +The PricingUnit column MUST be present in the billing data. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. Units of measure used in PricingUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The PricingUnit value MUST be semantically equal to the corresponding pricing measurement unit value provided in: diff --git a/specification/columns/usagequantity.md b/specification/columns/usagequantity.md deleted file mode 100644 index 5475c8ed9..000000000 --- a/specification/columns/usagequantity.md +++ /dev/null @@ -1,32 +0,0 @@ -# Usage Quantity - -The Usage Quantity represents the volume of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service) used or purchased, based on the [Usage Unit](#usageunit). Usage Quantity is often derived at a finer granularity or over a different time interval when compared to the [Pricing Quantity](#pricingquantity) (complementary to [Pricing Unit](#pricingunit)) and focuses on *resource* and *service* consumption, not pricing and cost. - -UsageQuantity column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type Decimal and MUST conform to [Numeric Format](#numericformat) requirements. The value MAY be negative in cases where [ChargeClass](#chargeclass) is "Correction". This column MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. - -## Column ID - -UsageQuantity - -## Display Name - -Usage Quantity - -## Description - -The volume of a given SKU associated with a *resource* or *service* used or purchased, based on the Usage Unit. - -## Content constraints - -| Constraint | Value | -|:----------------|:--------------| -| Column type | Metric | -| Feature level | Conditional | -| Allows nulls | True | -| Data type | Decimal | -| Value format | [Numeric Format](#numericformat) | -| Number range | Any valid decimal value | - -## Introduced (version) - -1.0-preview diff --git a/specification/columns/usageunit.md b/specification/columns/usageunit.md deleted file mode 100644 index 967e1fe9d..000000000 --- a/specification/columns/usageunit.md +++ /dev/null @@ -1,31 +0,0 @@ -# Usage Unit - -The Usage Unit represents a provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a [*resource*](#glossary:resource) or [*service*](#glossary:service). Usage Unit complements the [Usage Quantity](#usagequantity) metric. It is often listed at a finer granularity or over a different time interval when compared to the [Pricing Unit](#pricingunit) (complementary to [Pricing Quantity](#pricingquantity)), and focuses on *resource* and *service* consumption, not pricing and cost. - -The UsageUnit column MUST be present in the billing data when the provider supports the measurement of usage. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. Units of measure used in UsageUnit SHOULD adhere to the values and format requirements specified in the [UnitFormat](#unitformat) attribute. The UsageUnit column MUST NOT be used to determine values related to any pricing or cost metrics. - -## Column ID - -UsageUnit - -## Display Name - -Usage Unit - -## Description - -Provider-specified measurement unit indicating how a provider measures usage or purchase of a given SKU associated with a *resource* or *service*. - -## Content constraints - -| Constraint | Value | -|:----------------|:----------------| -| Column type | Metric | -| Feature level | Conditional | -| Allows nulls | True | -| Data type | String | -| Value format | [Unit Format](#unitformat) recommended | - -## Introduced (version) - -1.0-preview diff --git a/specification/glossary.md b/specification/glossary.md index 7e45a5db4..23e86b631 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -30,7 +30,7 @@ The time window that an organization receives an invoice for, inclusive of the s Block Pricing - A pricing approach where the cost of a particular resource or service is determined based on predefined quantities or tiers of usage. In these scenarios, the Pricing Unit and the corresponding Pricing Quantity can be different from the Usage Unit and Usage Quantity. + A pricing approach where the cost of a particular resource or service is determined based on predefined quantities or tiers of usage. In these scenarios, the Pricing Unit and the corresponding Pricing Quantity can be different from the Consumed Unit and Consumed Quantity. Charge diff --git a/supporting_content/columns/consumedquantity.md b/supporting_content/columns/consumedquantity.md new file mode 100644 index 000000000..968c6979d --- /dev/null +++ b/supporting_content/columns/consumedquantity.md @@ -0,0 +1,18 @@ +# Column: Consumed Quantity + +## Example provider mappings + +Current column mappings found in available data sets: + +| Provider | Data set | Column | +|----------|-------------------------|----------------------| +| AWS | CUR | lineItem/UsageAmount | +| Azure | Cost Details | quantity | +| GCP | BigQuery Billing Export | usage.amount | + +## Discussion Topics + +* May 6th, 2024: After much discussion, it was agreed upon by the maintainers to rename this column to 'ConsumedQuantity' and the related unit to 'ConsumedUnit' to reduce confusion between what AWS calls lineitem/UsageAmmount. The modification done to the previous UsageUnit content: Specify that this column applies only to 'Usage' rows - as it was previously written as 'usage or purchase'. That now becomes consistent with the subsequent sentence of the introductory paragraph which describes the column as measuring consumption. +* The examples in "Rows per Scenario V2" sheet in [this google sheet](https://docs.google.com/spreadsheets/d/1zA0brhrEntfWlzt5VNcNLBFnKPEiarajTF84o4ATeEw/edit#gid=1134244055) were helpful in understanding the need for a separate 'Consumed Quantity' as opposed to a single 'FooQuantity' (which later was voted to be 'ActualQuantity'). Rows 30/31/52/54/22 were helpful in showing the need to understand both the 'used' quantity and the quantity that you were charged for. +* Consensus was reached based on needing to support Staircase pricing - where you maybe charged for a quantity based on the 'stair' but you use less than that. It leads to the classic usage-optimization scenario in FinOps. For example, Slot usage in GCP BigQuery is charged based on a one minute minimum and per second granularity beyond that. Snowflake has similar scenario for warehouses. If you run a bunch of queries that use one-second, you're being charged for 60 seconds each time. Practitioners want to identify these and optimize their usage patterns to better utilize what they're paying for. To correctly identify the potential optimization opportunity, you need both pieces of data to show up in the data. ConsumedQuantity allows for the used amount to be presented in a consistent manner and is easily understood. +* The second column needed for the staircase pricing scenario above, a potential 'DistinctPricingQuantity' column, could be introduced in the future to identify the 60 seconds that you were 'charged' for in singular units. Today, you may have to use pricing quantity - which may have block pricing - therefore you may may need to do math to get 'distinct' units). Alternatively, we could introduce a 'factor' to remove the block portion of the pricing unit. This need was discussed and determined to be something that needs to be thought through and evaluated in detail post v1.0. diff --git a/supporting_content/columns/usageunit.md b/supporting_content/columns/consumedunit.md similarity index 64% rename from supporting_content/columns/usageunit.md rename to supporting_content/columns/consumedunit.md index 246933108..9077e6fe1 100644 --- a/supporting_content/columns/usageunit.md +++ b/supporting_content/columns/consumedunit.md @@ -1,4 +1,4 @@ -# Usage Unit +# Column: Consumed Unit ## Example provider mappings @@ -23,3 +23,5 @@ Current values observed in billing data for various scenarios: ## Discussion Topics * AWS and Azure Usage Units are not currently meeting the requirements recommended by the UnitFormat attribute. As such values from these providers are not recommended to be used directly. The formatting should be updated on values in Usage and Pricing Unit columns. +* May 6th, 2024: After much discussion, it was agreed upon by the maintainers to rename this column to 'ConsumedUnit' and the related quantity to 'ConsumedQuantity' to reduce confusion between what AWS calls lineitem/UsageAmmount. The modification done to the previous UsageUnit content: Specify that this column applies only to 'Usage' rows - as it was previously written as 'usage or purchase'. That now becomes consistent with the subsequent sentence of the introductory paragraph which describes the column as measuring consumption. +* More details on the May 6th, 2024 decision can be found in (consumedquantity)[../consumedquantity.md] supporting content. \ No newline at end of file diff --git a/supporting_content/columns/usagequantity.md b/supporting_content/columns/usagequantity.md deleted file mode 100644 index bf8365b56..000000000 --- a/supporting_content/columns/usagequantity.md +++ /dev/null @@ -1,11 +0,0 @@ -# Column: UsageQuantity - -## Example provider mappings - -Current column mappings found in available data sets: - -| Provider | Data set | Column | -|----------|-------------------------|----------------------| -| AWS | CUR | lineItem/UsageAmount | -| Azure | Cost Details | quantity | -| GCP | BigQuery Billing Export | usage.amount | From a9f6a16d0cc7ced6c2b26855e22f2f372bf3ea5d Mon Sep 17 00:00:00 2001 From: Udam Dewaraja Date: Thu, 9 May 2024 16:26:16 -0700 Subject: [PATCH 56/65] #436 Add helpful text for identifying records that need to be burned-down (#443) Resolves #436 - Add helpful text to help readers identify purchases eligible for burndown (billed cost >0 & effective cost = 0) - Add that Commitment-Based Discounts are an example of the described scenarios - Minor formatting fixes Co-authored-by: Joaquin --- specification/columns/contractedcost.md | 2 +- specification/columns/listcost.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/columns/contractedcost.md b/specification/columns/contractedcost.md index 34bc4fe35..a43cf0a64 100644 --- a/specification/columns/contractedcost.md +++ b/specification/columns/contractedcost.md @@ -2,7 +2,7 @@ Contracted Cost represents the cost calculated by multiplying [*contracted unit price*](#glossary:contracted-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). Contracted Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on negotiation activities, by comparing it with [List Cost](#listcost). If negotiated discounts are not applicable, the Contracted Cost defaults to the List Cost. -**Important:** When aggregating Contracted Cost for savings calculations, it's important to exclude either one-time or recurring charges ([ChargeCategory](#chargecategory)"Purchase") that are paid to cover future eligible charges or the covered charges themselves. This exclusion helps prevent double counting of these charges in the aggregation. Which set of charges to exclude depends on whether cost are aggregated on a billed basis (exclude covered charges) or accrual basis (exclude Purchases for future charges). For instance, charges categorized as [ChargeCategory](#chargecategory) "Purchase" and their related [ChargeCategory](#chargecategory) "Tax" charges for a [Commitment-Based Discount](#glossary:commitment-based-discount) might be excluded from an accrual basis cost aggregation of Contracted Cost. This is because the "Usage" and "Tax" charge records provided during the term of the commitment discount already specify the Contracted Cost. +**Important:** When aggregating Contracted Cost for savings calculations, it's important to exclude either one-time or recurring charges ([Charge Category](#chargecategory) "Purchase") that are paid to cover future eligible charges (e.g., [Commitment-Based Discount](#glossary:commitment-based-discount)) or the covered charges themselves. This exclusion helps prevent double counting of these charges in the aggregation. Which set of charges to exclude depends on whether cost are aggregated on a billed basis (exclude covered charges) or accrual basis (exclude Purchases for future charges). For instance, charges categorized as [Charge Category](#chargecategory) "Purchase" and their related [Charge Category](#chargecategory) "Tax" charges for a Commitment-Based Discount might be excluded from an accrual basis cost aggregation of Contracted Cost. This is because the "Usage" and "Tax" charge records provided during the term of the commitment discount already specify the Contracted Cost. Purchase charges that cover future eligible charges can be identified by filtering for [Charge Category](#chargecategory) "Purchase" records with a [Billed Cost](#billedcost) greater than 0 and an [Effective Cost](#effectivecost) equal to 0. The ContractedCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ContractedUnitPrice](#contractedunitprice) is present and not null, multiplying the ContractedUnitPrice by PricingQuantity MUST produce the ContractedCost, except in cases of [ChargeClass](#chargeclass) "Correction", which may address PricingQuantity or any cost discrepancies independently. diff --git a/specification/columns/listcost.md b/specification/columns/listcost.md index e5d296e3a..083e76dcb 100644 --- a/specification/columns/listcost.md +++ b/specification/columns/listcost.md @@ -2,7 +2,7 @@ List Cost represents the cost calculated by multiplying the [*list unit price*](#glossary:list-unit-price) and the corresponding [Pricing Quantity](#pricingquantity). List Cost is denominated in the [Billing Currency](#billingcurrency) and is commonly used for calculating savings based on various rate optimization activities, by comparing it with [Contracted Cost](#contractedcost), [Billed Cost](#billedcost) and [Effective Cost](#effectivecost). -**Important:** When aggregating ListCost for savings calculations, it's important to exclude either one-time or recurring charges ([ChargeCategory](#chargecategory)"Purchase") that are paid to cover future eligible charges or the covered charges themselves. This exclusion helps prevent double counting of these charges in the aggregation. Which set of charges to exclude depends on whether cost are aggregated on a billed basis (exclude covered charges) or accrual basis (exclude Purchases for future charges). For instance, charges categorized as [ChargeCategory](#chargecategory) "Purchase" and their related [ChargeCategory](#chargecategory) "Tax" charges for a [Commitment-Based Discount](#glossary:commitment-based-discount) might be excluded from an accrual basis cost aggregation of List Cost. This is because the "Usage" and "Tax" charge records provided during the term of the commitment discount already specify the List Cost. +**Important:** When aggregating List Cost for savings calculations, it's important to exclude either one-time or recurring charges ([Charge Category](#chargecategory) "Purchase") that are paid to cover future eligible charges (e.g., [Commitment-Based Discount](#glossary:commitment-based-discount)) or the covered charges themselves. This exclusion helps prevent double counting of these charges in the aggregation. Which set of charges to exclude depends on whether cost are aggregated on a billed basis (exclude covered charges) or accrual basis (exclude Purchases for future charges). For instance, charges categorized as [Charge Category](#chargecategory) "Purchase" and their related [Charge Category](#chargecategory) "Tax" charges for a Commitment-Based Discount might be excluded from an accrual basis cost aggregation of List Cost. This is because the "Usage" and "Tax" charge records provided during the term of the commitment discount already specify the List Cost. Purchase charges that cover future eligible charges can be identified by filtering for [Charge Category](#chargecategory) "Purchase" records with a [Billed Cost](#billedcost) greater than 0 and an [Effective Cost](#effectivecost) equal to 0. The ListCost column MUST be present in the billing data and MUST NOT be null. This column MUST be of type Decimal, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. When [ListUnitPrice](#listunitprice) is present and not null, multiplying the ListUnitPrice by PricingQuantity MUST produce the ListCost, except in cases of [ChargeClass](#chargeclass) "Correction", which may address PricingQuantity or any cost discrepancies independently. From 3ea2358a81aa9d2ad7a7c0e37fa207ef1a55b508 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Thu, 9 May 2024 16:28:07 -0700 Subject: [PATCH 57/65] [ADMIN] update release planning based on the Consistency Review delay. (#445) This PR provides new dates for the next steps of IPR Review, WG Approval, and Steering Committee Ratifications. The delay in completing the Consistency Review by a week has triggered these changes. Also, we add some days to prepare the final baseline after completing the Consistency Review. --- RELEASE-PLANNING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RELEASE-PLANNING.md b/RELEASE-PLANNING.md index 05dfdabb4..4352d40cc 100644 --- a/RELEASE-PLANNING.md +++ b/RELEASE-PLANNING.md @@ -22,22 +22,22 @@ This estimated time line was approved by the Members working group on the Feb 29 Incoming issues will be prioritized by maintainers. Only P0 and some P1 issues will get added to the v1.0 milestone. Prioritization will take voting and comments in issues into consideration - Apr 25 - May 02 + Apr 25 - May 09 Final Consistency Review Freeze working-draft.
Final review, only expecting editorial comments. - May 2 - May 31 + May 13 - June 11 IPR Review Members may exclude any Essential Claims from their licensing commitments during this period. - June 6 + June 13 Release Candidate Approve by the WG Members - Jun 6 + Jun 19 Steering Committee Ratifies the Release From 17f8b371e4f513a1ea7b648a235ee5bacce88071 Mon Sep 17 00:00:00 2001 From: Udam Dewaraja Date: Thu, 9 May 2024 16:30:14 -0700 Subject: [PATCH 58/65] #441 Clarifications for various Commitment discount scenarios (#444) Resolves the concerns in #441 related to representing Commitment-based discount purchases and corresponding usage (for both CommitmentDiscountStatus "Used" and "Unused") scenarios Co-authored-by: Joaquin --- specification/attributes/discount_handling.md | 5 +++-- specification/columns/commitmentdiscountstatus.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/specification/attributes/discount_handling.md b/specification/attributes/discount_handling.md index 79a3a7e2a..b641646ed 100644 --- a/specification/attributes/discount_handling.md +++ b/specification/attributes/discount_handling.md @@ -34,9 +34,10 @@ Indicates how to include and apply discounts to usage charges or rows. * Purchased discounts (e.g., commitment-based discounts) MUST be amortized. * The BilledCost MUST be 0 for any row where the commitment covers the entire cost for the charge period. * The EffectiveCost MUST include the portion of the amortized purchase cost that applies to this row. - * CommitmentDiscountStatus MUST be "Used" for rows that received a reduced price from that commitment. - * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. CommitmentDiscountStatus MUST be "Unused". * The sum of the EffectiveCost for all rows where CommitmentDiscountStatus is "Used" or "Unused" for each CommitmentDiscountId over the entire duration of the commitment MUST be the same as the total BilledCost of the commitment-based discount. + * The CommitmentDiscountId and ResourceId MUST be set to the ID assigned to the commitment-based discount. ChargeCategory MUST be set to "Purchase" on rows that represent a purchase of a commitment-based discount. + * CommitmentDiscountStatus MUST be "Used" for ChargeCategory "Usage" rows that received a reduced price from a commitment. CommitmentDiscountId MUST be set to the ID assigned to the discount. ResourceId MUST be set to the ID of the resource that received the discount. + * If a commitment is not fully utilized, the provider MUST include a row that represents the unused portion of the commitment for that charge period. These rows MUST be represented with CommitmentDiscountStatus set to "Unused" and ChargeCategory set to "Usage". Such rows MUST have their CommitmentDiscountId and ResourceId set to the ID assigned to the commitment-based discount. * Credits that are applied after the fact MUST use a ChargeCategory of "Credit". ## Exceptions diff --git a/specification/columns/commitmentdiscountstatus.md b/specification/columns/commitmentdiscountstatus.md index a0d58bf4b..31da82f9c 100644 --- a/specification/columns/commitmentdiscountstatus.md +++ b/specification/columns/commitmentdiscountstatus.md @@ -2,7 +2,7 @@ Commitment Discount Status indicates whether the charge corresponds with the consumption of the [*commitment-based discount*](#glossary:commitment-based-discount) identified in the CommitmentDiscountId column or the unused portion of the committed amount. -The CommitmentDiscountStatus column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null. The CommitmentDiscountCategory MUST be one of the allowed values. +The CommitmentDiscountStatus column MUST be present in the billing data when the provider supports *commitment-based discounts*. This column MUST be of type String, MUST be null when [CommitmentDiscountId](#commitmentdiscountid) is null, and MUST NOT be null when CommitmentDiscountId is not null and [Charge Category](#chargecategory) is "Usage". The CommitmentDiscountCategory MUST be one of the allowed values. ## Column ID From adc1623c7e66463b98ff1ebed9a8b4fc5606f37c Mon Sep 17 00:00:00 2001 From: Andrew Qu <115758900+aqu-erp@users.noreply.github.com> Date: Thu, 9 May 2024 16:53:28 -0700 Subject: [PATCH 59/65] #441 ChargePeriod Start and End spec change (#442) Based on #441 Clarifying description and normative statements for expected values between usage, time-bound purchase, and time-agnostic purchase scenarios ### v2 ChargePeriodStart >ChargePeriodStart MUST be present in the billing data, MUST be of type Date/Time, MUST be an *inclusive* value, and MUST NOT contain null values. ChargePeriodStart MUST match the beginning date and time boundary of the effective period of the charge. ChargePeriodEnd > ChargePeriodEnd MUST be present in the billing data, MUST be of type Date/Time, MUST be an *exclusive* value, and MUST NOT contain null values. ChargePeriodEnd MUST match the ending date and time boundary of the effective period of the charge. Note: there is a grey area when [ChargeCategory](#chargecategory) is "Purchase" and the charge does not contain an expiration or ending date and time boundary.
### v1 ChargePeriodStart >ChargePeriodStart MUST be present in the billing data, MUST be of type Date/Time, MUST be an *inclusive* value, and MUST NOT contain null values. ChargePeriodStart MUST match the beginning date and time boundary for which a charge is active. ChargePeriodEnd > ChargePeriodEnd MUST be present in the billing data, MUST be of type Date/Time, MUST be an *exclusive* value, and MUST NOT contain null values. When [ChargeCategory](#chargecategory) is "Purchase" and the charge contains an expiration or ending date and time boundary, ChargePeriodEnd MUST match the ending date and time boundary for which the charge is active.
--- specification/columns/chargeperiodend.md | 2 +- specification/columns/chargeperiodstart.md | 2 +- specification/glossary.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/columns/chargeperiodend.md b/specification/columns/chargeperiodend.md index f017bb747..053c905c9 100644 --- a/specification/columns/chargeperiodend.md +++ b/specification/columns/chargeperiodend.md @@ -2,7 +2,7 @@ Charge Period End represents the [*exclusive*](#glossary:exclusivebound) end date and time of a [*charge period*](#glossary:chargeperiod). For example, a time period where [ChargePeriodStart](#chargeperiodstart) is '2024-01-01T00:00:00Z' and ChargePeriodEnd is '2024-01-02T00:00:00Z' includes charges for January 1, since ChargePeriodStart is [*inclusive*](#glossary:inclusivebound), but does not include charges for January 2 since ChargePeriodEnd is *exclusive*. -ChargePeriodEnd MUST be present in the billing data, MUST be of type Date/Time, MUST be an *exclusive* value, and MUST NOT contain null values. +ChargePeriodEnd MUST be present in the billing data, MUST be of type Date/Time, MUST be an *exclusive* value, and MUST NOT contain null values. ChargePeriodEnd MUST match the ending date and time boundary of the effective period of the charge. ## Column ID diff --git a/specification/columns/chargeperiodstart.md b/specification/columns/chargeperiodstart.md index 3c9347d07..18c8c9c5a 100644 --- a/specification/columns/chargeperiodstart.md +++ b/specification/columns/chargeperiodstart.md @@ -2,7 +2,7 @@ Charge Period Start represents the [*inclusive*](#glossary:inclusivebound) start date and time within a [*charge period*](#glossary:chargeperiod). For example, a time period where ChargePeriodStart is '2024-01-01T00:00:00Z' and [ChargePeriodEnd](#chargeperiodend) is '2024-01-02T00:00:00Z' includes charges for January 1, since ChargePeriodStart is *inclusive*, but does not include charges for January 2 since ChargePeriodEnd is [*exclusive*](#glossary:exclusivebound). -ChargePeriodStart MUST be present in the billing data, MUST be of type Date/Time, MUST be an *inclusive* value, and MUST NOT contain null values. +ChargePeriodStart MUST be present in the billing data, MUST be of type Date/Time, MUST be an *inclusive* value, and MUST NOT contain null values. ChargePeriodStart MUST match the beginning date and time boundary of the effective period of the charge. ## Column ID diff --git a/specification/glossary.md b/specification/glossary.md index 23e86b631..22d19d859 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -38,7 +38,7 @@ A row in a FOCUS-compatible cost and usage dataset. Charge Period -The time window in which a charge was incurred, inclusive of the start date and exclusive of the end date. A charge can start and/or end at any time within a charge period window. The charge period for continuous usage should match the time granularity of the dataset (e.g., 1 hour for hourly, 1 day for daily). +The time window for which a charge is effective, inclusive of the start date and exclusive of the end date. The charge period for continuous usage should match the time granularity of the dataset (e.g., 1 hour for hourly, 1 day for daily). The charge period for a non-usage charge with time boundaries should match the duration of eligibility. Commitment From dbaa0f148a1a58d55810f01594f6b486b31adbf2 Mon Sep 17 00:00:00 2001 From: Irena Jurica Date: Fri, 10 May 2024 16:05:14 +0200 Subject: [PATCH 60/65] FOCUS #425: ChargeClass (Path 1) - spec updates and associated columns adjustments (#432) - ChargeClass spec change: - Clarification indicating that Corrections apply specifically to charges invoiced in previous billing periods. - Allowed values reduced to 'Correction'; otherwise, null is expected. - Consequential spec changes of the following columns: - ContractedUnitPrice - ListUnitPrice - PricingCategory - PricingQuantity - PricingUnit - SkuId - SkuPriceId - UsageQuantity - UsageUnit - Changelog adjustments --------- Co-authored-by: Udam Dewaraja Co-authored-by: Michael Flanakin Co-authored-by: Graham --- CHANGELOG.md | 12 ++++----- specification/columns/chargeclass.md | 13 +++++---- specification/columns/contractedunitprice.md | 2 +- specification/columns/listunitprice.md | 2 +- specification/columns/pricingcategory.md | 2 +- specification/columns/skuid.md | 2 +- specification/columns/skupriceid.md | 2 +- supporting_content/columns/chargeclass.md | 26 ++++++++++++++++++ supporting_content/columns/skupriceid.md | 28 ++++++++++---------- 9 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 supporting_content/columns/chargeclass.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f081ba97..6dcfaa0d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,19 +48,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Specified that in the case of a purchase charge paid to cover future eligible charges, the Effective Cost is set to 0. - `ListUnitPrice` column updates: - Column is conditional and only required when the provider publishes a price list that excludes discounts. - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". - `PricingCategory` column updates: - Column is conditional and only required when the provider supports more than one pricing category value. - Changed "On-Demand" to "Standard". - Changed "Commitment-Based" to "Committed". - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". - `PricingQuantity` - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". - `PricingUnit` - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". - `ResourceId` column updates: - Column is conditional and only required when the provider supports billing based on provisioned resource instances. @@ -70,11 +70,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Column is conditional and only required when the provider supports billing based on provisioned resource instances and supports multiple "types" of resources. - `SkuId` column updates: - Column is conditional and only required when the provider publishes a SKU list. - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". - `SkuPriceId` column updates: - Column is conditional and only required when the provider publishes a SKU price list. - - Must not be null when `ChargeClass` is "Regular" and `ChargeCategory` is "Usage" or "Purchase". + - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". - `SubAccountId` column updates: - Column is conditional and only required when the provider supports a sub account construct. diff --git a/specification/columns/chargeclass.md b/specification/columns/chargeclass.md index 1fbde4945..9cd710888 100644 --- a/specification/columns/chargeclass.md +++ b/specification/columns/chargeclass.md @@ -1,8 +1,8 @@ # Charge Class -A Charge Class indicates whether the row represents a regular charge or a correction to one or more previous charges. Charge Class is commonly used to differentiate refunds from regularly incurred charges. +Charge Class indicates whether the row represents a correction to one or more [*charges*](#glossary:charge) invoiced in a previous billing period. Charge Class is commonly used to differentiate corrections from regularly incurred charges. -The ChargeClass column MUST be present and MUST NOT be null. This column is of type String and MUST be one of the allowed values. +The ChargeClass column MUST be present in the billing data. This column MUST be of type String and MUST be "Correction" when the row represents a correction to one or more charges invoiced in a previous billing period. ChargeClass MUST be null when it is not a correction or when it is a correction within the current billing period. ## Column ID @@ -14,7 +14,7 @@ Charge Class ## Description -Indicates whether the row represents a regular charge or a correction to one or more previous charges, its primary use is for differentiating refunds from normal usage. +Indicates whether the row represents a correction to one or more *charges* invoiced in a previous billing period. ## Content Constraints @@ -22,7 +22,7 @@ Indicates whether the row represents a regular charge or a correction to one or | :-------------- | :------------- | | Column type | Dimension | | Feature level | Mandatory | -| Allows nulls | False | +| Allows nulls | True | | Data type | String | | Value format | Allowed values | @@ -30,9 +30,8 @@ Allowed values: | Value | Description | | :--------- | :------------------------------------| -| Standard | Standard charges for services used or purchased. | -| Correction | Modification to one or more previous charges, like refunds and credit modifications. | +| Correction | Correction to one or more charges invoiced in previous billing periods (e.g., refunds and credit modifications). | ## Introduced (version) -0.5 +1.0 diff --git a/specification/columns/contractedunitprice.md b/specification/columns/contractedunitprice.md index 25fc0e595..00eb8f4ce 100644 --- a/specification/columns/contractedunitprice.md +++ b/specification/columns/contractedunitprice.md @@ -2,7 +2,7 @@ The Contracted Unit Price represents the agreed-upon unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, inclusive of negotiated discounts, if present, while excluding negotiated commitment-based discounts or any other discounts. This price is denominated in the [Billing Currency](#billingcurrency). The Contracted Unit Price is commonly used for calculating savings based on negotiation activities. If negotiated discounts are not applicable, the Contracted Unit Price defaults to the [List Unit Price](#listunitprice). -The ContractedUnitPrice column MUST be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost), except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. +The ContractedUnitPrice column MUST be present in the billing data when the provider supports negotiated pricing concept. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. It MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When ContractedUnitPrice is present and not null, multiplying ContractedUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ContractedCost](#contractedcost), except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. ## Column ID diff --git a/specification/columns/listunitprice.md b/specification/columns/listunitprice.md index ea1295a42..7cab32e2d 100644 --- a/specification/columns/listunitprice.md +++ b/specification/columns/listunitprice.md @@ -2,7 +2,7 @@ The List Unit Price represents the suggested provider-published unit price for a single [Pricing Unit](#pricingunit) of the associated SKU, exclusive of any discounts. This price is denominated in the [Billing Currency](#billingcurrency). The List Unit Price is commonly used for calculating savings based on various rate optimization activities. -The ListUnitPrice column MUST be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost), except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. +The ListUnitPrice column MUST be present in the billing data when the provider publishes unit prices exclusive of discounts. This column MUST be a Decimal within the range of non-negative decimal values, MUST conform to [Numeric Format](#numericformat) requirements, and be denominated in the BillingCurrency. It MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. When ListUnitPrice is present and is not null, multiplying ListUnitPrice by [PricingQuantity](#pricingquantity) MUST equal [ListCost](#listcost), except in cases of ChargeClass "Correction", which may address PricingQuantity or any cost discrepancies independently. ## Column ID diff --git a/specification/columns/pricingcategory.md b/specification/columns/pricingcategory.md index 4bd45e32f..641b71074 100644 --- a/specification/columns/pricingcategory.md +++ b/specification/columns/pricingcategory.md @@ -5,7 +5,7 @@ Pricing Category describes the pricing model used for a charge at the time of us The PricingCategory column adheres to the following requirements: * PricingCategory MUST be present in the billing data when the provider supports more than one pricing category across all SKUs and MUST be of type String. -* PricingCategory MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. +* PricingCategory MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. * PricingCategory MUST be one of the allowed values. * PricingCategory MUST be "Standard" when pricing is predetermined at the agreed upon rate for the [billing account](#glossary:billing-account). * PricingCategory MUST be "Committed" when [CommitmentDiscountId](#commitmentdiscountid) is not null. diff --git a/specification/columns/skuid.md b/specification/columns/skuid.md index f63f66310..5a4a93f1a 100644 --- a/specification/columns/skuid.md +++ b/specification/columns/skuid.md @@ -2,7 +2,7 @@ A SKU ID is a unique identifier that defines a provider-supported construct for organizing properties that are common across one or more [*SKU Prices*](#glossary:sku-price). SKU ID can be referenced on a catalog or [*price list*](#glossary:price-list) published by a provider to look up detailed information about the SKU. The composition of the properties associated with the SKU ID may differ across providers. Some providers may not support the [*SKU*](#glossary:sku) construct and instead associate all such properties directly with the *SKU Price*. SKU ID is commonly used for analyzing cost based on *SKU*-related properties above the pricing constructs. -The SkuId column MUST be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. +The SkuId column MUST be present in the billing data when the provider publishes a SKU list. This column MUST be of type String. It MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct. ## Column ID diff --git a/specification/columns/skupriceid.md b/specification/columns/skupriceid.md index 36aacbbe0..3c5ad2bf2 100644 --- a/specification/columns/skupriceid.md +++ b/specification/columns/skupriceid.md @@ -2,7 +2,7 @@ A SKU Price ID is a unique identifier that defines the unit price used to calculate the charge. SKU Price ID can be referenced on a [*price list*](#glossary:price-list) published by a provider to look up detailed information, including a corresponding list unit price. The composition of the properties associated with the SKU Price ID may differ across providers. SKU Price ID is commonly used for analyzing cost based on pricing properties such as Terms and Tiers. -The SkuPriceId column MUST be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. This column MUST NOT be null when [ChargeClass](#chargeclass) is "Standard" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. +The SkuPriceId column MUST be present in the billing data when the provider publishes a SKU price list. This column MUST be of type String. SkuPriceId MUST define a single unit price used for calculating the charge. The [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published *price list*. This column MUST NOT be null when [ChargeClass](#chargeclass) is not "Correction" and [ChargeCategory](#chargecategory) is "Usage" or "Purchase", MUST be null when ChargeCategory is "Tax", and MAY be null for all other combinations of ChargeClass and ChargeCategory. A given value of SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of commitment discount flexibility. ## Column ID diff --git a/supporting_content/columns/chargeclass.md b/supporting_content/columns/chargeclass.md new file mode 100644 index 000000000..be91dbc8d --- /dev/null +++ b/supporting_content/columns/chargeclass.md @@ -0,0 +1,26 @@ +# Column: Charge Class + +## Discussion / Scratch space + +### Discussion on column nullability and allowed values + +* Initially, ChargeClass was defined as a non-nullable column with two allowed values: Regular and Correction. +* Various alternative names for Regular charges were discussed, including Regular, Standard, Original, and Direct. +* Eventually, the team decided on a nullable column approach, where Correction is the sole allowed value, representing corrections to one or more charges invoiced in a previous billing period. + +### Impacts of 1.0 ChargeCategory and ChargeClass cleanup + +The following table serves as the basis for reviewing the SkuPriceId spec, as well as price, cost, quantity metrics, etc., impacted by the ChargeCategory and ChargeClass columns cleanup. + +| ChargeCategory | ChargeClass | perSku/bulk | SkuId | SkuPriceId | +|----------------|-------------|--------------------------------|------------------|------------------| +| Usage | (null) | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | +| Usage | Correction | MAY be bulk | MAY be null | MAY be null | +| Purchase | (null) | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | +| Purchase | Correction | MAY be bulk | MAY be null | MAY be null | +| Credit | (null) | MAY be bulk | MAY be null | MAY be null | +| Credit | Correction | MAY be bulk | MAY be null | MAY be null | +| Adjustment | (null) | MAY be bulk | MAY be null | MAY be null | +| Adjustment | Correction | MAY be bulk | MAY be null | MAY be null | +| Tax | (null) | MUST be bulk | MUST be null | MUST be null | +| Tax | Correction | MUST be bulk | MUST be null | MUST be null | diff --git a/supporting_content/columns/skupriceid.md b/supporting_content/columns/skupriceid.md index f3b3dffe6..0e0d105e3 100644 --- a/supporting_content/columns/skupriceid.md +++ b/supporting_content/columns/skupriceid.md @@ -36,17 +36,17 @@ Current values observed in billing data for various scenarios: ### Impacts of 1.0 ChargeCategory and ChargeClass cleanup -The following table serves as the basis for reviewing the SkuPriceId spec, as well as price, cost, quantity metrics, etc., impacted by the ChargeCategory and ChargeClass columns cleanup - -| ChargeCategory | ChargeClass | perSku/bulk | SkuId | SkuPriceId | -|----------------|-------------|-----------------------------------|------------------|------------------| -| Usage | Regular | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | -| Usage | Correction | MAY be bulk | MAY be null | MAY be null | -| Purchase | Regular | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | -| Purchase | Correction | MAY be bulk | MAY be null | MAY be null | -| Credit | Regular | MAY be bulk | MAY be null | MAY be null | -| Credit | Correction | MAY be bulk | MAY be null | MAY be null | -| Adjustment | Regular | MAY be bulk | MAY be null | MAY be null | -| Adjustment | Correction | MAY be bulk | MAY be null | MAY be null | -| Tax | Regular | MUST be bulk | MUST be null | MUST be null | -| Tax | Correction | MUST be bulk | MUST be null | MUST be null | +The following table serves as the basis for reviewing the SkuPriceId spec, as well as price, cost, quantity metrics, etc., impacted by the ChargeCategory and ChargeClass columns cleanup. + +| ChargeCategory | ChargeClass | perSku/bulk | SkuId | SkuPriceId | +|----------------|-----------------------------------------|-----------------------------------|------------------|------------------| +| Usage | Regular/Standard/Original/Direct/(null) | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | +| Usage | Correction | MAY be bulk | MAY be null | MAY be null | +| Purchase | Regular/Standard/Original/Direct/(null) | MUST be perSku and perSkuPrice | MUST not be null | MUST not be null | +| Purchase | Correction | MAY be bulk | MAY be null | MAY be null | +| Credit | Regular/Standard/Original/Direct/(null) | MAY be bulk | MAY be null | MAY be null | +| Credit | Correction | MAY be bulk | MAY be null | MAY be null | +| Adjustment | Regular/Standard/Original/Direct/(null) | MAY be bulk | MAY be null | MAY be null | +| Adjustment | Correction | MAY be bulk | MAY be null | MAY be null | +| Tax | Regular/Standard/Original/Direct/(null) | MUST be bulk | MUST be null | MUST be null | +| Tax | Correction | MUST be bulk | MUST be null | MUST be null | From a0ee2842c88013ef92b8f4cf16338223a00923a4 Mon Sep 17 00:00:00 2001 From: rileyjenk Date: Fri, 10 May 2024 10:31:15 -0600 Subject: [PATCH 61/65] Thanking Potato for its contribution. (#448) --- specification/glossary.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specification/glossary.md b/specification/glossary.md index 22d19d859..938cd28ec 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -108,6 +108,10 @@ A term that describes a service that is available and provided immediately or as An individual who performs FinOps within an organization to maximize the business value of using cloud and cloud-like services. +Potato + +A long and often painful conversation had by the FOCUS contributors. Sometimes the name of a thing that we could not yet name. No starchy root vegetables were harmed during the production of this specification. We thank potato for its contribution in the creation of this specification. + Provider An entity that made internal or 3rd party resources and/or services available for purchase. From a23ad8007e036b11a1d541e0b484966ff09ccb84 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Tue, 14 May 2024 10:03:28 +1000 Subject: [PATCH 62/65] Version update for 1.0 Release (#456) Bump version ready for 1.0 release Update year in copyright --------- Signed-off-by: Mike Fuller --- specification/versions/candidate_release.md | 4 ++-- specification/versions/main.md | 4 ++-- specification/versions/working_draft.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/versions/candidate_release.md b/specification/versions/candidate_release.md index 4da911b32..536156fe9 100644 --- a/specification/versions/candidate_release.md +++ b/specification/versions/candidate_release.md @@ -1,12 +1,12 @@ ## Version -v1.0-Preview Candidate Release +v1.0 Candidate Release | ⚡ Warning | |:-------------------------------------------------------------------------------| | This version is a candidate release but not an official publication | -Copyright © 2023 - FinOps Open Cost and Usage Specification (FOCUS) a Series of the Joint Development Foundation Projects, LLC. Linux Foundation [trademark](https://www.linuxfoundation.org/legal/trademarks), and document use rules apply. +Copyright © 2024 - FinOps Open Cost and Usage Specification (FOCUS) a Series of the Joint Development Foundation Projects, LLC. Linux Foundation [trademark](https://www.linuxfoundation.org/legal/trademarks), and document use rules apply. ## Status of This Document diff --git a/specification/versions/main.md b/specification/versions/main.md index 769131edf..abf1c7eff 100644 --- a/specification/versions/main.md +++ b/specification/versions/main.md @@ -1,8 +1,8 @@ ## Version -Publication version 1.0-Preview +Publication version 1.0 -Copyright © 2023 - FinOps Open Cost and Usage Specification (FOCUS) a Series of the Joint Development Foundation Projects, LLC. Linux Foundation [trademark](https://www.linuxfoundation.org/legal/trademarks), and document use rules apply. +Copyright © 2024 - FinOps Open Cost and Usage Specification (FOCUS) a Series of the Joint Development Foundation Projects, LLC. Linux Foundation [trademark](https://www.linuxfoundation.org/legal/trademarks), and document use rules apply. ## Status of This Document diff --git a/specification/versions/working_draft.md b/specification/versions/working_draft.md index e9c175a71..a6ada5a48 100644 --- a/specification/versions/working_draft.md +++ b/specification/versions/working_draft.md @@ -6,7 +6,7 @@ Working Draft (Unversioned) |:-------------------------------------------------------------------------------| | This version not for publication | -Copyright © 2023 - FinOps Open Cost and Usage Specification (FOCUS) a Series of the Joint Development Foundation Projects, LLC. Linux Foundation [trademark](https://www.linuxfoundation.org/legal/trademarks), and document use rules apply. +Copyright © 2024 - FinOps Open Cost and Usage Specification (FOCUS) a Series of the Joint Development Foundation Projects, LLC. Linux Foundation [trademark](https://www.linuxfoundation.org/legal/trademarks), and document use rules apply. ## Status of This Document From 52ed731a1319a7252fce487513cac5a3f1c54dd8 Mon Sep 17 00:00:00 2001 From: Christopher Harris Date: Mon, 13 May 2024 20:06:51 -0400 Subject: [PATCH 63/65] Update contributors.md (#429) Add additional sections for Steering Committee and Maintainers. --------- Co-authored-by: Joaquin Co-authored-by: Karl <133434112+kk09v@users.noreply.github.com> Co-authored-by: AWS-ZachErdman <157180770+AWS-ZachErdman@users.noreply.github.com> Co-authored-by: rileyjenk Co-authored-by: Joaquin Co-authored-by: Udam Dewaraja Co-authored-by: Michael Flanakin --- specification/contributors.md | 58 ++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/specification/contributors.md b/specification/contributors.md index 81076d2fe..2674fe1e6 100644 --- a/specification/contributors.md +++ b/specification/contributors.md @@ -1,7 +1,27 @@ -## Contributors +## Working Group -Thanks to the following FOCUS members for their contributions to this specification. +### Maintainers +Thanks to the following FOCUS Maintainers for their leadership and contributions to the FOCUS specification. + +* Christopher Harris (Datadog) +* Dennis Park-Rodriguez (Amazon Web Services) +* Erik Peterson (CloudZero) +* Irena Jurica (Neos) +* Joaquin Prado (FinOps Foundation) +* Karl Kraft (Walmart) +* Larry Advey (Twilio) +* Michael Flanakin (Microsoft) +* Mike Fuller (FinOps Foundation) +* Riley Jenkins (Domo) +* Rupa Patel (Google) +* Udam Dewaraja (FinOps Foundation) + +### Contributors + +Thanks to the following FOCUS members for their contributions to the FOCUS specification. + +* Adam Schwartz (Ernst & Young) * Alex Hullah (Goldman Sachs) * Amit Wadhwa (Google) * Anand Tripathi (Amazon Web Services) @@ -15,47 +35,55 @@ Thanks to the following FOCUS members for their contributions to this specificat * Casey Doran (Apptio) * Chandra Devarajan (CloudTrakr) * Chew Esmero (Alphaus Inc.) -* Christopher Harris (Datadog) * Colin Jack (Snow Software) * Deeja Cruz (Datadog) * Eleni Rundle (Google) -* Erik Peterson (CloudZero) +* George Parker (Salesforce) * Graham Murphy (Australian Retirement Trust) -* Irena Jurica (Neos) -* Jacky Liu (Google) +* Harish Kumar Munagapat (Kyndryl) +* Hrishikesh Sardar (Kyndryl) +* Ilia Semenov (CloudThread) +* Jacky Liu (Google Cloud) +* Jacqui Wilson (Old Mutual South Africa) * Janine Pickard-Green (MagicOrange Group Limited) * Jason Kelly (Anglepoint Group Inc) * Joe Ferrero (DB Gurus Inc) * John Grubb (Platform.sh) * Joshua Kwan (Ternary) -* Karl Kraft (Walmart) -* Larry Advey (Twilio) * Letian Wang (Atlassian) * Luna Bernal (Twilio) -* Marc Perreaut (amadeus) +* Marc Perreaut (Amadeus) * Marcin Walkow (Nordcloud) * Mark Krawczeniuk (NetApp) * Matt Ray (Kubecost) * Michael Arkoosh (Vega) -* Michael Flanakin (Microsoft) -* Mike Fuller (FinOps Foundation) * Mike Polson (VMWare) * Nick Kotze (Surveil) * Nicolas Fonrose (Teevity) * Peter Marton (OpenMeter.io) * Ray Ding (Accenture) * Ricardo Triana (Accenture) -* Riley Jenkins (Domo) * Rodney Joyce (CloudMonitor) -* Rupa Patel (Google) * Sanjna Srivatsa (VMWare) -* Sarah McMullin (Google) * Shawn Alpay (Envisor) +* Sireesha Oram (Kyndryl) +* Sonal Garg (Kyndryl) * Sumaira Nazir (Platform.sh) * Tatiana Dubovchenko (Flexera) * Tim O'Brien (Walmart) * Trey Morgan (Microsoft) * Trig Ghosh (Accenture) -* Udam Dewaraja (FinOps Foundation) * Webb Brown (Kubecost) * Yuriy Prykhodko (Amazon Web Services) +* Zach Erdman (Amazon Web Services) + +## Steering Committee Members + +Thanks to the following FOCUS Steering Committee members for their leadership on the FOCUS specification. + +* Anne Johnston (Capital One) +* Michael Flanakin (Microsoft) +* Mike Fuller (FinOps Foundation) +* Roy Wolman (Amazon Web Services) +* Sarah McMullin (Google) +* Tim O'Brien (Walmart) From c708d68c8397bcec4a060bd0bc3661c0b0b6a0cb Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Tue, 14 May 2024 10:07:33 +1000 Subject: [PATCH 64/65] Update Use Case examples with new column names #452 (#454) Signed-off-by: Mike Fuller Co-authored-by: Udam Dewaraja Co-authored-by: Irena Jurica Co-authored-by: Michael Flanakin --- specification/use_case_library.md | 76 +++++++++++++++---------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/specification/use_case_library.md b/specification/use_case_library.md index d21c1afce..535cb9ec5 100644 --- a/specification/use_case_library.md +++ b/specification/use_case_library.md @@ -5,42 +5,42 @@ The following table contains a set of commonly performed FinOps scenarios that w | Persona | Capability | Use Case | FOCUS Columns | |:--|:--|:--|:--| | Business / Product Owner | Budget Management | As a Business/Product Owner, I need to compare actual usage costs incurred within a time period to the amount forecasted. | BilledCost
BillingAccountId
BillingAccountName
ChargePeriodStart
ChargePeriodEnd
ChargeCategory
Provider | -| Engineering & Operations | Budget Management | As an Engineering Manager who wants to reduce their billed cost for Compute for a specific provider, I want to understand what is my current rate of Commitment based discount (without negotiated discounts) per type of commitment, so that I can strategize further purchases | BillingPeriodStart
CommitmentDiscountType
EffectiveCost
Provider
ServiceName
SubAccountId
SubAccountName | -| Engineering & Operations | Data Analysis and Showback | As an Engineer, I want to understand the costs of the components that belong to an application | ChargeDescription
ChargePeriodStart
EffectiveCost
ResourceId
ResourceName
ResourceType
ServiceCategory
ServiceName
SKUId
Tags | -| Engineering & Operations | Data Analysis and Showback | As an Engineer, I want to understand the costs of the components for a specific resource | ChargePeriodStart
EffectiveCost
ResourceId
ResourceName
SKUId | -| Engineering & Operations | Data Analysis and Showback | As an Engineer, I want to understand the costs of all components and resources within a subaccount | ChargePeriodStart
EffectiveCost
ResourceId
ResourceName
SKUId
SubAccountID | -| Engineering & Operations | Data Analysis and Showback | As an Engineering & Operations person I would like to analyze the usage of serverless requests on a weekly basis to identity potential optimization candidates | BilledCost
Provider
ChargePeriodStart
ChargePeriodEnd
SkuId
UsageQuantity
Tags
UsageUnit | -| Engineering & Operations | Data Analysis and Showback | As an Engineer, I need to extract a ranked list of the top 10 service cost drivers within a sub account from a time period | ChargePeriodStart
EffectiveCost
SubAccountID
SubAccountName
ServiceName | -| Engineering & Operations | Workload Management & Automation | As an Engineer I need to ensure my costs within a region are distributed across the different availability zones in an expected manner. | Provider
AvailabilityZone
Region
BillingPeriodStart
EffectiveCost | -| Engineering & Operations | Workload Management & Automation | As an Engineering manager, I need to see the cost of each compute resource in a production SubAccount I'm responsible for. | ResourceID
ResourceName
ChargePeriodStart
ChargePeriodEnd
ServiceName
ServiceCategory
PricingQuantity
EffectiveCost | -| Finance | Budget Management | As a person in Finance, I need to update cloud budget with actual cost details within a billing period | BilledCost
BillingPeriodStart
BillingPeriodEnd
Provider | -| Finance | Budget Management | As a person in Finance, I need to update budget, by application, with actual cost details within a billed time period | BilledCost
BillingPeriodStart
BillingPeriodEnd
Provider
Tags | -| Finance | Budget Management | As a person in Finance, I need to track tax costs month over month. | BillingPeriodStart
BilledCost
ChargeCategory
Provider | +| Engineering & Operations | Budget Management | As an Engineering Manager who wants to reduce their billed cost for Compute for a specific provider, I want to understand what is my current rate of Commitment based discount (without negotiated discounts) per type of commitment, so that I can strategize further purchases | BillingPeriodStart
CommitmentDiscountType
EffectiveCost
ProviderName
ServiceName
SubAccountId
SubAccountName | +| Engineering & Operations | Data Analysis and Showback | As an Engineer, I want to understand the costs of the components that belong to an application | ChargeDescription
ChargePeriodStart
EffectiveCost
ResourceId
ResourceName
ResourceType
ServiceCategory
ServiceName
SkuId
Tags | +| Engineering & Operations | Data Analysis and Showback | As an Engineer, I want to understand the costs of the components for a specific resource | ChargePeriodStart
EffectiveCost
ResourceId
ResourceName
SkuId | +| Engineering & Operations | Data Analysis and Showback | As an Engineer, I want to understand the costs of all components and resources within a subaccount | ChargePeriodStart
EffectiveCost
ResourceId
ResourceName
SkuId
SubAccountId | +| Engineering & Operations | Data Analysis and Showback | As an Engineering & Operations person I would like to analyze the usage of serverless requests on a weekly basis to identity potential optimization candidates | BilledCost
ProviderName
ChargePeriodStart
ChargePeriodEnd
SkuId
ConsumedQuantity
Tags
ConsumedUnit | +| Engineering & Operations | Data Analysis and Showback | As an Engineer, I need to extract a ranked list of the top 10 service cost drivers within a sub account from a time period | ChargePeriodStart
EffectiveCost
SubAccountId
SubAccountName
ServiceName | +| Engineering & Operations | Workload Management & Automation | As an Engineer I need to ensure my costs within a region are distributed across the different availability zones in an expected manner. | ProviderName
AvailabilityZone
RegionId
RegionName
BillingPeriodStart
EffectiveCost | +| Engineering & Operations | Workload Management & Automation | As an Engineering manager, I need to see the cost of each compute resource in a production SubAccount I'm responsible for. | ResourceId
ResourceName
ChargePeriodStart
ChargePeriodEnd
ServiceName
ServiceCategory
PricingQuantity
EffectiveCost | +| Finance | Budget Management | As a person in Finance, I need to update cloud budget with actual cost details within a billing period | BilledCost
BillingPeriodStart
BillingPeriodEnd
ProviderName | +| Finance | Budget Management | As a person in Finance, I need to update budget, by application, with actual cost details within a billed time period | BilledCost
BillingPeriodStart
BillingPeriodEnd
ProviderName
Tags | +| Finance | Budget Management | As a person in Finance, I need to track tax costs month over month. | BillingPeriodStart
BilledCost
ChargeCategory
ProviderName | | Finance | Budget Management | As a Financial Analyst or member of the company's treasury, I would like to understand what volume of commitment based charges are going to reoccur in the coming financial year | ChargeFrequency
BillingPeriodStart
BilledCost | -| Finance | Data Analysis and Showback | As a Finance person of a company that sells SaaS services, I need to determine the resource quantity and type used by a customer so that a monthly invoice can be issued to the customer. | Provider
BillingPeriodStart
SKU
UsageQuantity
UsageUnit
Tags | -| Finance | Data Analysis and Showback | As a person in Finance, I need a report of all cost associated with a product from all geographic locations for a given month. | BilledCost
BilledCurrency
BillingAccountId
BillingAccountName
BillingPeriodEnd
Provider
Tags | -| Finance | FinOps & Intersecting Frameworks | As a person in Finance, I need a report of service-level cost within a specific Sub Account as a part of a private pricing negotiation. | BillingPeriodStart
EffectiveCost
Provider
ServiceName
SubAccountID
SubAccountName | -| Finance | Forecasting | As a person in Finance, I need to forecast amortized costs on a month over month basis, based on historical trends | BillingPeriodStart
ChargeType
EffectiveCost
PricingUnit
Provider
ServiceType
ServiceCategory | -| Finance | Forecasting | As a person in Finance, I need to forecast cashflow on a month over month basis, based on historical trends | BillingPeriodStart
ChargeType
ChargeDescription
BilledCost
PricingUnit
Provider
ServiceType
ServiceCategory | -| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I need to analyze service costs month over month, over a time period | EffectiveCost
BillingPeriodStart
Provider
ServiceName | -| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I need to analyze service costs, by region, over a time period | EffectiveCost
BillingPeriodStart
Provider
Region
ServiceName | -| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I need to analyze Compute Engine service costs month over month for a period of time to identify accounts spending the most money on Compute Engine | BilledCost
BillingPeriodStart
Provider
ResourceId
ResourceName
ServiceName
SubAccountId
SubAccountName | -| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I want to monitor how much we are spending on a specific SaaS product purchased via the cloud service provider's marketplace. | ChargePeriodStart
ChargePeriodEnd
EffectiveCost
InvoiceIssuer
Provider
Publisher | -| FinOps Practitioner | Data Analysis and Showback | As a FinOps Practitioner, I need to understand what we are spending across providers, billing periods, and service categories | Provider
BillingPeriodStart
BilledCost
BillingCurrency
ServiceCategory | -| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to verify the accuracy of the cloud service provider invoices | Provider
BillingAccountID
BillingAccountName
BillingPeriodStart
BilledCost
BillingCurrency | -| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to verify the accuracy of the cloud service provider invoices and the underlying services | Provider
BillingAccountID
BillingAccountName
BillingPeriodStart
BilledCost
BillingCurrency
ServiceName | -| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to reconcile discounts on the cloud service provider invoices and the underlying services | Provider
BillingAccountId
BillingAccountName
BillingPeriodStart
BilledCost
BillingCurrency
EffectiveCost
ListCost
ServiceName | -| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to analyze usage data of resources | ChargePeriodStart
ChargeCategory
EffectiveCost
Provider
QuantityInUsageUnit
ResourceId
ServiceName
SKUId
UsageUnit | -| FinOps Practitioner | Forecasting | As a FinOps Practitioner, I need to forecast costs, based on historical usage trends and rates | BillingPeriodStart
ChargeType
ChargeDescription
EffectiveCost
Provider
UsageQuantity
Region
ServiceCategory
ServiceName
SKUId
UsageUnit | -| FinOps Practitioner | Managing Anomalies | As a FinOps Practitioner, I need to see the daily costs across all cloud providers, billing accounts, and sub accounts | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
Provider
EffectiveCost | -| FinOps Practitioner | Managing Anomalies | As a FinOps Practitioner, I need to see the daily costs across all cloud providers, billing accounts, sub accounts, and region | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
EffectiveCost
Provider
Region | -| FinOps Practitioner | Managing Anomalies | As a FinOps practitioner, I need to see the daily costs across all cloud providers, billing accounts, sub accounts, and service | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
EffectiveCost
Provider
ServiceName | -| FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track all commitment based discounts purchased for a time period | Provider
BillingAccountID
CommitmentDiscountId
CommitmentDiscountType
BilledCost
ChargePeriodStart
ChargeCategory | -| FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track unused commitment charges in any given time period so that I consider them in my future commitment planning or remedy them | CommitmentDiscountStatus (filter)
CommitmentDiscountID
BilledCost
ChargePeriodStart | -| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture. | ChargeType
ChargeDescription
ChargePeriodStart
Provider
ResourceType
SubAccountID
ServiceName | -| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture within a specific service | ChargeType
ChargeDescription
ChargePeriodStart
Provider
ResourceType
SubAccountID
ServiceName | -| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to identify total refunds within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeCategory
ChargeClass | -| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to identify refunds across sub accounts within a billing period. | Provider
BillingAccountID
ServiceCategory
BilledCost
BillingPeriodStart
ChargeCategory
ChargeClass
SubAccountID | -| FinOps Practitioner | Workload Management & Automation | As a FinOps Practitioner, I need to do an analysis on compliance to data residency requirements across all regions | ChargePeriodStart
Provider
Region
SubAccountID | -| Procurement | Data Analysis and Showback | As a person in Procurement, I need to understand what we are spending, across billing periods, across service categories to focus negotiations toward highest costing items | Provider
BillingAccountID
BillingAccountName
BillingCurrency
BilledCost
BillingPeriodStart
ServiceCategory
ServiceName | -| Procurement, Finance, FinOps Practitioner | FinOps & Intersecting Frameworks | Multiple personas in an organization need to know the top SKU Codes based on spend, so that they can achieve multiple goals such as contract negotiation, SKU based forecasting, or high unit cost cleanup activities. | ChargePeriodStart
ChargePeriodEnd
ListCost
PricingUnit
ListUnitPrice
PricingQuantity
SKUId
SKUPriceId
Provider | +| Finance | Data Analysis and Showback | As a Finance person of a company that sells SaaS services, I need to determine the resource quantity and type used by a customer so that a monthly invoice can be issued to the customer. | ProviderName
BillingPeriodStart
SkuId
PricingQuantity
ConsumedQuantity
ConsumedUnit
Tags | +| Finance | Data Analysis and Showback | As a person in Finance, I need a report of all cost associated with a product from all geographic locations for a given month. | BilledCost
BillingCurrency
BillingAccountId
BillingAccountName
BillingPeriodEnd
ProviderName
Tags | +| Finance | FinOps & Intersecting Frameworks | As a person in Finance, I need a report of service-level cost within a specific Sub Account as a part of a private pricing negotiation. | BillingPeriodStart
EffectiveCost
ProviderName
ServiceName
SubAccountId
SubAccountName | +| Finance | Forecasting | As a person in Finance, I need to forecast amortized costs on a month over month basis, based on historical trends | BillingPeriodStart
ChargeCategory
EffectiveCost
PricingUnit
ProviderName
ServiceName
ServiceCategory | +| Finance | Forecasting | As a person in Finance, I need to forecast cashflow on a month over month basis, based on historical trends | BillingPeriodStart
ChargeCategory
ChargeDescription
BilledCost
BillingCurrency
ProviderName
ServiceName
ServiceCategory | +| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I need to analyze service costs month over month, over a time period | EffectiveCost
BillingPeriodStart
ProviderName
ServiceName | +| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I need to analyze service costs, by region, over a time period | EffectiveCost
BillingPeriodStart
ProviderName
RegionId
RegionName
ServiceName | +| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I need to analyze Compute Engine service costs month over month for a period of time to identify accounts spending the most money on Compute Engine | BilledCost
BillingPeriodStart
ProviderName
ResourceId
ResourceName
ServiceName
SubAccountId
SubAccountName | +| FinOps Practitioner | Data Analysis and Showback | As a FinOps practitioner, I want to monitor how much we are spending on a specific SaaS product purchased via the cloud service provider's marketplace. | ChargePeriodStart
ChargePeriodEnd
EffectiveCost
InvoiceIssuer
ProviderName
Publisher | +| FinOps Practitioner | Data Analysis and Showback | As a FinOps Practitioner, I need to understand what we are spending across providers, billing periods, and service categories | ProviderName
BillingPeriodStart
BilledCost
BillingCurrency
ServiceCategory | +| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to verify the accuracy of the cloud service provider invoices | ProviderName
BillingAccountId
BillingAccountName
BillingPeriodStart
BilledCost
BillingCurrency | +| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to verify the accuracy of the cloud service provider invoices and the underlying services | ProviderName
BillingAccountId
BillingAccountName
BillingPeriodStart
BilledCost
BillingCurrency
ServiceName | +| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to reconcile discounts on the cloud service provider invoices and the underlying services | ProviderName
BillingAccountId
BillingAccountName
BillingPeriodStart
BilledCost
BillingCurrency
EffectiveCost
ListCost
ServiceName | +| FinOps Practitioner | FinOps & Intersecting Frameworks | As a FinOps Practitioner, I need to analyze usage data of resources | ChargePeriodStart
ChargeCategory
EffectiveCost
ProviderName
PricingQuantity
ConsumedQuantity
ResourceId
ServiceName
SkuId
ConsumedUnit | +| FinOps Practitioner | Forecasting | As a FinOps Practitioner, I need to forecast costs, based on historical usage trends and rates | BillingPeriodStart
ChargeCategory
ChargeDescription
EffectiveCost
ProviderName
PricingQuantity
ConsumedQuantity
RegionId
ServiceCategory
ServiceName
SkuId
ConsumedUnit | +| FinOps Practitioner | Managing Anomalies | As a FinOps Practitioner, I need to see the daily costs across all cloud providers, billing accounts, and sub accounts | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
ProviderName
EffectiveCost | +| FinOps Practitioner | Managing Anomalies | As a FinOps Practitioner, I need to see the daily costs across all cloud providers, billing accounts, sub accounts, and region | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
EffectiveCost
ProviderName
RegionId
RegionName | +| FinOps Practitioner | Managing Anomalies | As a FinOps practitioner, I need to see the daily costs across all cloud providers, billing accounts, sub accounts, and service | BillingAccountId
SubAccountId
ChargePeriodStart
ChargePeriodEnd
EffectiveCost
ProviderName
ServiceName | +| FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track all commitment based discounts purchased for a time period | ProviderName
BillingAccountId
CommitmentDiscountId
CommitmentDiscountType
BilledCost
ChargePeriodStart
ChargeCategory | +| FinOps Practitioner | Managing Commitment Based Discounts | As a FinOps Practitioner, I want to track unused commitment charges in any given time period so that I consider them in my future commitment planning or remedy them | CommitmentDiscountStatus (filter)
CommitmentDiscountId
BilledCost
ChargePeriodStart | +| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture. | ChargeCategory
ChargeDescription
ChargePeriodStart
ProviderName
ResourceType
SubAccountId
ServiceName | +| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to analyze the fleet diversity in order to run a campaign to standardize application architecture within a specific service | ChargeCategory
ChargeDescription
ChargePeriodStart
ProviderName
ResourceType
SubAccountId
ServiceName | +| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to identify total refunds within a billing period. | ProviderName
BillingAccountId
ServiceCategory
BilledCost
BillingPeriodStart
ChargeCategory
ChargeClass | +| FinOps Practitioner | Resource Utilization & Efficiency | As a FinOps Practitioner, I need to identify refunds across sub accounts within a billing period. | ProviderName
BillingAccountId
ServiceCategory
BilledCost
BillingPeriodStart
ChargeCategory
ChargeClass
SubAccountId | +| FinOps Practitioner | Workload Management & Automation | As a FinOps Practitioner, I need to do an analysis on compliance to data residency requirements across all regions | ChargePeriodStart
ProviderName
RegionId
RegionName
SubAccountId | +| Procurement | Data Analysis and Showback | As a person in Procurement, I need to understand what we are spending, across billing periods, across service categories to focus negotiations toward highest costing items | ProviderName
BillingAccountId
BillingAccountName
BillingCurrency
BilledCost
BillingPeriodStart
ServiceCategory
ServiceName | +| Procurement, Finance, FinOps Practitioner | FinOps & Intersecting Frameworks | Multiple personas in an organization need to know the top SKU Codes based on spend, so that they can achieve multiple goals such as contract negotiation, SKU based forecasting, or high unit cost cleanup activities. | ChargePeriodStart
ChargePeriodEnd
ListCost
PricingUnit
ListUnitPrice
PricingQuantity
SkuId
SkuPriceId
ProviderName | From c0aab63e879afc0f9834dec0500a563fc819a218 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Mon, 13 May 2024 17:09:38 -0700 Subject: [PATCH 65/65] [EDITORIAL] Update changelog (#455) ### Question for the Group - [ ] Since v1.0-preview all the columns have been updated. Should we reflect these changes in the column `Latest Update` of the `Column History` section. - [ ] The group needs to review sections v1.0 sections: `Changed` and `Fixed` as I am unclear what the changes are. --------- Co-authored-by: Michael Flanakin Co-authored-by: Udam Dewaraja --- CHANGELOG.md | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dcfaa0d3..4aa3045de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## v1.0 + +Announced June 20, 2024 **Added:** @@ -62,6 +64,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `PricingUnit` - Must not be null when `ChargeClass` is not "Correction" and `ChargeCategory` is "Usage" or "Purchase". - Must be null when `ChargeCategory` is "Tax". +- `RegionId` column updates: + - `Region` column was renamed to `RegionId` when `RegionName` column was introduced - `ResourceId` column updates: - Column is conditional and only required when the provider supports billing based on provisioned resource instances. - `ResourceName` column updates: @@ -91,13 +95,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), **Removed:** - `ChargeSubcategory` column - See `ChargeCategory` and `ChargeClass` columns -- `Region` column - See `RegionId` and `RegionName` columns [All unreleased changes](https://github.com/FinOps-Open-Cost-and-Usage-Spec/FOCUS_Spec/compare/v1.0-preview-cr...working_draft)
## v1.0-preview + Announced November 15, 2023 **Added:** @@ -177,8 +181,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), This table maps the evolution of the billing data, showcasing column introductions and updates from its initial version 0.5 to the comprehensive revisions in "1.0-preview", "1.0" and beyond. -| **Column ID** | **Revision Introduced** | **Latest Update** | +| **Column ID** | **Revision Introduced** | **Status** | |------------------------------|-------------------------|-------------------| +| AmortizedCost | 0.5 | Renamed to EffectiveCost in v1.0-preview | | AvailabilityZone | 0.5 | | | BilledCost | 0.5 | | | BillingAccountId | 0.5 | | @@ -186,31 +191,34 @@ This table maps the evolution of the billing data, showcasing column introductio | BillingCurrency | 0.5 | | | BillingPeriodEnd | 0.5 | | | BillingPeriodStart | 0.5 | | -| ChargeCategory | 0.5 | 1.0 | +| ChargeType | 0.5 | Renamed to ChargeCategory in v1.0-preview | +| ChargeCategory | 1.0-preview | Renamed from ChargeType in v1.0-preview | | ChargeClass | 1.0 | | | ChargeDescription | 1.0-preview | | | ChargeFrequency | 1.0-preview | | | ChargePeriodEnd | 0.5 | | | ChargePeriodStart | 0.5 | | -| ChargeSubcategory | 1.0-preview | Removed in 1.0 | +| ChargeSubcategory | 1.0-preview | Removed in v1.0 | | CommitmentDiscountCategory | 1.0-preview | | | CommitmentDiscountId | 1.0-preview | | | CommitmentDiscountName | 1.0-preview | | | CommitmentDiscountStatus | 1.0 | | | CommitmentDiscountType | 1.0-preview | | +| ConsumedQuantity | 1.0 | Renamed from UsageQuantity in v1.0 | +| ConsumedUnit | 1.0 | Renamed from UsageUnit in v1.0 | | ContractedCost | 1.0 | | | ContractedUnitPrice | 1.0 | | -| EffectiveCost | 0.5 | | -| InvoiceIssuerName | 0.5 | | +| EffectiveCost | 1.0-preview | Renamed from AmortizedCost in v1.0-preview | +| InvoiceIssuerName | 0.5 | | | ListCost | 1.0-preview | | | ListUnitPrice | 1.0-preview | | -| PricingCategory | 1.0-preview | 1.0 | +| PricingCategory | 1.0-preview | | | PricingQuantity | 1.0-preview | | | PricingUnit | 1.0-preview | | | ProviderName | 0.5 | | | PublisherName | 0.5 | | -| Region | 0.5 | Removed in 1.0 | -| RegionId | 1.0 | | +| Region | 0.5 | Renamed to RegionId in v1.0 | +| RegionId | 1.0 | Renamed from Region in v1.0 | | RegionName | 1.0 | | | ResourceId | 0.5 | | | ResourceName | 0.5 | | @@ -218,9 +226,9 @@ This table maps the evolution of the billing data, showcasing column introductio | ServiceCategory | 0.5 | | | ServiceName | 0.5 | | | SkuId | 1.0-preview | | -| SkuPriceId | 1.0-preview | 1.0 | +| SkuPriceId | 1.0-preview | | | SubAccountId | 0.5 | | | SubAccountName | 0.5 | | -| Tags | 1.0-preview | 1.0 | -| UsageQuantity | 1.0-preview | | -| UsageUnit | 1.0-preview | | +| Tags | 1.0-preview | | +| UsageQuantity | 1.0-preview | Renamed to ConsumedQuantity in v1.0 | +| UsageUnit | 1.0-preview | Renamed to ConsumedUnit in v1.0 |