Dimensions & CostFormation

CloudZero Dimensions are the solution for understanding all the costs of operating cloud software in all the ways that matter to the business. Dimensions allow you to use some characteristic of cloud infrastructure (usually accounts, services or tags) and categorize it. You can think of Dimensions as a meta-tagging layer that sits on top of all the various pieces of metadata we have about resources. Most organizations using CloudZero will have multiple Dimensions. The Dimensions you create can be used in many different ways throughout the product; to group and filter spend in the Explorer, to receive updates via Slack or email through Views, to understand cost per customer, and more.

It’s important to understand high level terminology before starting to build Dimensions. Dimensions begin with charges. A charge is the dollar amount that the cloud provider billed for a given thing at a given time. Elements are the various values that a charge may have in a Dimension. For example, us-east-1 is an Element of the region Dimension. In practice, Elements are usually referred to using the Dimension name; e.g. “us-east-1 is a region in the region Dimension,” “Billing is a feature in the feature Dimension.” Every cost and usage report line item (which you can generalize to resource) can only have 1 Element value per Dimension.

Dimensions are implemented via CloudZero’s proprietary CostFormation language. We provide an extension for Microsoft’s Visual Studio Code (VS Code) to help customer’s build / maintain Dimensions.

In order to get started creating Dimensions, you’ll need 3 things:

  • Have “Organizer” permissions within the CloudZero Platform
  • Install Microsoft’s VS Code
  • Install CloudZero’s extension from VS Code’s marketplace

Terminology
Dimension - CloudZero context that implements business logic

Element - Each value within a Dimension. This is what is created by the logic of the Dimension.

Example

Customer ← Dimension

CloudZero ← Element

Demandbase ← Element

ASICS ← Element

CostFormation Syntax
CostFormation is a proprietary CloudZero language built on top of YAML. The YAML syntax is always the same for CloudZero dimension definitions and it’s important to understand the structure and spacing:


Line 1 - This is the DimensionID. It needs to be unique across all dimensions and is the way you’ll reference this dimension in another dimension configuration if necessary.

Line 2 - This is the friendly Name for the dimension. This is what will be listed in the Explorer UI

Line 4 - This is the start of the various rules / logic you want to configure for the dimension. Each Type: Group represents a new “block” of logic to create one “element”. Always remember that YAML files are processed sequentially, from the top down.

  • NOTE - There are a number of different types of rules each with their own syntax. Group is the most basic and probably most widely used type. Each rule type will be described in the CostFormation Rules section below.

Line 5 - This is the friendly Name for the dimension element you’re about to configure logic for. This name differs from the name on line 2 in that line 2 specifies the friendly name for the whole dimension, while this name is the friendly name for this particular element within the dimension.

Line 7 - These are the Source(s) that the logic will match against. There can be one or more of these. If there are multiple sources listed, the logic will be evaluated against each source and the results will be OR’d together. See here for a full list of the possible sources.

Line 10 - Transforms are a way to affect the source values before they’re evaluated against your matching criteria (see line 12). Since some of the metadata sources (see line 7) are based on user input, the values can’t be controlled (casing, spacing, etc..). This needs to be considered when building your dimension element logic. See here for a full list of the possible transforms.

Line 12 - Specifies the operator and the logic for the condition. See here for a full list of the possible conditional operators. We would recommend postponing review of that section for now, as it may cause confusion before you have gone through several examples.

Each CUR line item will be evaluated against the logic in your CostFormation YAML, starting from the top and processing sequentially to the bottom. The first block where the logic evaluates to TRUE, that CUR line item will get the corresponding element name. A Dimension is then an aggregation of all the CUR line items that have been assigned the various element names based on the CostFormation logic in the YAML.

CostFormation Rule Types / Logic

CostFormation is the language CloudZero developed to help describe the logic you want to define the elements of a dimension. The full documentation can be found here (it’s thorough). You should think of this logic like a SQL CASE statement or an IF/THEN/ELSE statement. Every line item in the cost-and-usage data is processed against the CostFormation for a dimension (sequentially). Once a line item matches a conditional statement, it’s associated to whatever element the condition describes. Any given line item can only be associated to a single Dimension element.

The example above illustrates the most basic form of dimension remapping. While this alone offers numerous use cases, the true potential lies in the variety of rules and data sources available, and the ability to combine them in multiple ways.

Rules Types
Looking at the dimension example above, each element of the array under the main Rules section represents a rule. There are 4 main types to be aware of:

Logic - IF Source:Service = “OCBPremiumSupport” THEN “Support”

Description - The Group rule lets you define the exact logic you want to drive a particular element (in this case “Support”). It’s probably the most commonly used rule both because of it’s usefulness and simplicity.

Logic - No Logic. Take all the values from Normalize(Source:Tag:Name) and creates elements for them

Description - Quite often customers will have “good” tags they want to use to drive the dimension logic. The GroupBy rule let’s you quickly take the values from the customer’s good source (and apply a transform if you want).

Logic - IF (Source:Service = “AmazonWorkDocs” AND Normalize(Source:UsageType) = “listapicalls” THEN “ListAPICalls”

ELSEIF (Source:Service = “AmazonWorkDocs” AND Normalize(Source:UsageType) = “readapicalls” THEN “ReadAPICalls”

ELSEIF (Source:Service = “AmazonWorkDocs” AND Normalize(Source:UsageType) = “writeapicalls” THEN “WriteAPICalls”

END

Description - The metadata rule is really a convenience rule. This type of rule could easily be done with a Group rule, but it can get verbose. This just let’s you implement fuzzy matching more easily. The one thing to be aware of is that the source and values are always normalized before evaluating the logic and the condition is always CONTAINS


Logic - Take the spend identified by the “SpendToAllocate” filter state and proportionally / evenly split it across whatever items are defined in the “AcrossElements” definition. In this case, I want to take all the support charges in payer account “949156204738” (which will all land in the “949156204738” account) and proportionally “spread” that across all the accounts in payer account “949156204738”.

Description - Proportional / even allocation rules are a very easy way to help customers who want to fully allocate their spend. The most important thing to remember about using allocation dimensions is that the output of this dimension only contains the spend defined in the “SpendToAllocate”. This means if you wanted a “final” account dimension that contained all the spend in the accounts + the support allocation you’d need another “GroupBy” rule that coalesced the dimension defined above and “Source: Account”.


Logic - Take the spend defined by the “Targets” in the telemetry streams referenced and allocate that proportionally based on the “Elements” (per day)

Description - Telemetry driven allocation rules are a more robust / precise method for allocating spend. A customer takes some usage metric outside of cost, and sends that into the platform via a telemetry API. The dimension definition above then translates that usage data into cost allocation. Much like proportional / even split allocation rules above, the output of the telemetry allocation dimension will only contain the spend defined in the targets of the stream(s). If multiple streams are listed, then these are evaluated in priority order. Any given resource’s allocation can only be defined by 1 set of allocation rules.