Guide to Using the CostFormation Definition Language

A guide to understanding how to build Custom Dimensions using CloudZero CostFormation

This section will help you understand how to create Custom Dimensions using CostFormation to build dimension definitions. CostFormation defines a syntax which is based on YAML and is used to define the properties of a Custom Dimension, the rules that define the Elements of the dimension, and the conditions under which charges are placed into the element.

📘

Key Terms

Dimension
A way of viewing your cloud costs broken down into different groups or Elements

Custom Dimension
A dimension created with custom logic specific to your organization that allows you to view your cloud costs in the context of your business or engineering needs

Element
A group of related charges within a Dimension

Charge
A single line item of cloud cost or collection of cloud costs

YAML Syntax

YAML is a human friendly data serialization language which works well with other programmatic languages. If you are not familiar with YAML, you can do a simple search for YAML Tutorial using your favorite search engine and find many sites and videos that can teach you the basics of YAML. For some quick information and links, you can visit the YAML Wikipedia page.

Structure in YAML

YAML relies on white space (spaces, indexes, and newlines) to create structure within a YAML document. Any line or lines that are indented using one or more spaces from a previous line is considered to be part of the structure of the previous line. For example:

Root:
  Property1: Value1
  Property2:
    Property2-A: Value2-A
    Property2-B: Value2-A
  Property3:
    Property3-A: Value3-1

In the above example, Root is an object that contains the properties Property1, Property2, and Property3 as they are indented by two spaces in from Root. Property1 is assigned the value Value1 while Property2 is another object containing the properties Property2-A and Property2-B. The end of Property2 is indicated by Property3 as it is indented at the same level as Property1 and Property2 and is therefore a part of the object Root.

For CostFormation, there are three key YAML constructs you must be familiar with: key/value pairs, lists, and objects.

Key/Value Pairs

Key/Values pairs are used to create properties and assign them values. For example:

Animal: Dog
Breed: Pug
Age: 5

In the above examples, the keys are Animal, Breed, and Age. Their respective values are Dog, Pug, and 5. Keys must be a string while property values can be strings, integers, boolean values (i.e. True or False), lists, and objects.

Lists

In YAML, the value in the Key/Value pair can be a list. Lists can be denoted two ways. With indented lines that start with dashes:

Toys:
  - Car
  - Ball
  - Doll

As a comma delimited list within square brackets:

Toys: [Car, Ball, Doll]

The above examples are equivalent.

Objects

In YAML, the value in the Key/Value pair can be another object with its own key/value pairs. For example:

Ball1:
  Sport: Soccer
  Color: Black and White
  Material: Leather
Ball2:
  Sport: Football
  Color: Brown
  Material: Leather

The above example shows Ball1 and Ball2 as objects with properties defining attributes of each ball.

CostFormation Definition File

All Custom Dimension definitions are placed in a single CostFormation Definition File which can be downloaded from CloudZero, edited to add, remove, or modify your Custom Dimensions, and then uploaded to publish the new Custom Dimensions. This file contains the YAML based definitions for one or more Custom Dimensions.

📘

Modifying Custom Dimension Definitions

Currently modifying and uploading the CostFormation Definitions File must be performed by the CloudZero Customer Success team. Please contact your Customer Success representative to work with you to create or modify Custom Dimensions for your organization.

The CostFormation Definition File must contain the root key Dimensions followed by one or more Custom Dimension definitions. Each definition comprises a key, which is the dimension's ID, and a set of properties which define the attributes of the Custom Dimension. The basic structure will look as follows:

Dimensions:
  <Dimension 1 Id>:
    <Dimension 1 Properties>
  <Dimension 2 Id>:
    <Dimension 2 Properties>
  ...
  <Dimension N Id>:
    <Dimension N Properties>

For example:

Dimensions:
  Country:
    Name: Custom Country Dimension
    DefaultValue: global
    Child: Region
    Rules:
      - Type: GroupBy
        Source: Region
        Transforms:
          - Type: Split. # This transform splits a string on '-' and takes the first item
            Delimiter: '-'  # For example, if the source value is "us-east-1" it would be transformed to "us"
            Index: 0
          - Type: Lower # Lowercases the string; for example "US" would become "us"

  AccountName:
    Name: Account Name
    Disable: true
    Source: Account
    Groups:
        Prod Feature A:
          - Equals: 0123456789010  # Any account with id 0123456789010 will be grouped under "Prod Feature A"
        Prod Feature B:
          - Equals: 0123456789011
        Dev Feature A:
          -Equals:
            - 0123456789012  # Any account with either id 0123456789012 or 0123456789013 will be grouped under "Dev Feature A"
            - 0123456789013
        Dev Feature B:
          - Equals:
            - 0123456789014
            - 0123456789015

This definitions file above declares two new dimensions: Country and AccountName.

Defining a Custom Dimension

A Custom Dimension definition consists of a unique ID and a set of properties that define attributes of the dimension - such as its name, or whether it should be made visible to users in CloudZero or not - as well as the rules that define the dimension. It may also optionally specify a default source to be used in the rules and conditions for the definition.

A Custom Dimension definition has the following structure:

  <DimensionId>:
    Name: <Dimension Name>
    Hide: <True|False>
    Disable: <True|False>
    Child: <Another Dimension>
    DefaultValue: <Default Element Name>

    <Source Properties>
    <Rules> | <AllocateByStreams> | <AllocateByRules>

The DimensionId is a unique identifier that can be used when referencing this custom dimension as a source value in other custom dimensions. It will also be used as the visible name of the dimension if the Name property is not specified.

The following are the properties of a dimension definition.

PropertyTypeRequired?Available ForDescription
NameStringNoAllThis property provides a user visible name for the custom dimension. This is the name that will be visible in areas such as the Explorer. If not present, the ID will be used as the name.
HideBooleanNoAllIf set to True, the dimension will not be visible in CloudZero, but the dimension can be used as a source for other dimensions. Otherwise the dimension will be visible to all users. This allows you to create some dimensions that are not meant to be used directly by your users, but rather are meant to be building blocks for other dimensions.
DisableBooleanNoAllIf set to True this dimension will not be compiled and will not be visible in CloudZero and cannot be used as a source for other dimensions. It allows you to remove the dimension without fully deleting it. If this is not set, it will default to False.
ChildStringNoAllThis property identifies the next logical dimension in the hierarchy. Currently, this field's value is used to determine the next GroupBy value when drilling down in the Explorer. Any valid Source is a valid Child. For example, the Child of PaymentOption is Service, meaning when viewing data grouped by PaymentOption the next logical grouping is Service.
OverrideStringNoGroup dimensions only
DefaultValueStringNoAllThis property indicates the name of the Element to place any charge that does not match any rules in the definition.

See Applying Rules for more information on how this property is used.
<Source Properties>Collection of propertiesNoAllThis is a collection of properties that identify source dimensions as well as ways to manipulate the incoming data before rules and conditions are applied.

See Specifying Sources for more information on the source properties.
TypeStringNoAllThis defines the type of custom dimension. Possible values are "Allocation" or "Grouping". If omitted, it will default to "Grouping"
<Rules>Object or list of objectsYesGroup dimensions onlyThis section contains the rules and conditions for grouping the sources into elements.

See Adding Rules for the different rule structures.
AllocateByStreams | AllocateByRulesObject or list of objectsYesAllocation dimensions onlyThis section defines how the cost allocations will be split. See Adding Allocations for more information on creating allocations.

Overriding Default Dimensions

There are a number of custom dimensions that are provided by default to all customers. The definitions for these dimensions are maintained by CloudZero. If for some reason, the default definition of a particular dimension does not suit your particular needs, you may override the it with your own definition in your custom definition file. This can be done simply by setting the Override field in your custom dimension to reference the default dimension you wish to override.

For example:

  Elasticity:
    Name: Elasticity
    Override: CZ:Defined:Elasticity
    ....

The Override field is required in order to override the default dimension. Without this field, the above definition would fail validation because the name Elasticity collides with the name of the default dimension CZ:Defined:Elasticity. However, adding the Override field and the ID of the default dimension, CZ:Defined:Elasticity, you are explicitly specifying that you want this definition to be used in place of the default definition.

Any other dimensions, whether in the default dimensions definitions or in your own custom definitions, that reference the overridden default dimension, will be automatically adjusted to reference the new dimension in your custom definitions.

📘

Override Capabilities and Restrictions

The following capabilities and restrictions apply when overriding default dimensions:

  • Only default dimensions can be overridden. You cannot specify another custom dimensions from the User:Defined namespace as the override target.
  • A default dimension can only be overridden by one custom dimension.
  • All dimensions names, whether it is a default dimension or a custom dimension, must be unique, unless the matching names are from a custom dimension and the default dimension it is overriding.
  • When specifying that a custom dimension overrides a default dimension, neither the ID nor the name of the custom dimension needs to match those of the overridden default dimension. Either or both may be different.

See Additional Cloud Provider Dimensions for a list of default dimensions or Default Dimension Definitions for their current definitions.

Specifying Sources

When defining a Custom Dimension, you need to designate the source of the data against which the rules and conditions are applied. Any other dimension can be used as a source, including Core Dimensions, Tag Dimensions, Kubernetes Dimensions, CloudZero provided Dimensions, and other Custom Dimensions. For a full list of dimensions and their source IDs, see the reference documentation.

Sources can be specified in different locations of a Custom Dimension definition. They can be defined in the root of the definition as well as in a rule or in a condition. Source properties are inherited but can be overridden. This means that any sources specified at the root level of the definition will be applied to any rules and conditions that do not have a source specified within the rule or condition. Likewise, a source specified at the rule level will be applied to all conditions within the rule unless a source is specified within the condition. Any rule or condition that specifies its own source properties will use those source properties and ignore any inherited source properties.

For example:

  Environment:
    Name: Environment
    Source: Account
    Rules:
      - Type: Group
        Name: Production
        Conditions:
          - Equals:
              - 123456789010
              - 123456789011
              - 123456789012
      - Type: Group
        Name: DevOps
        Conditions:
          - Source: CZ:Defined:Category
            Equals: Cloud Management
          - Source: Service
            Contains: Support
      - Type: Group
        Name: Development
        Conditions:
          - Equals:
            - 123456789013
            - 123456789014

In the above example, the source dimension, Account, is specified in the root of the definition and is used by default for any rule or condition that does not specify its own source. So in the first rule (Name: Production) the condition checks if Account is equal to 123456789010, 123456789011, or 123456789012. However, in the second rule (Name: DevOps) the conditions both specify a source. So the first condition in that second rule checks if the source CZ:Defined:Category equals Cloud Management or if the source Service equals Support. The third rule (Name: Development) uses the Account as its source.

Sources can always be specified using a collection of properties.

PropertyTypeRequiredDescription
Source (or Sources)String or a list of strings.YesThis property identifies one or more source dimensions. It specifies a single dimension as a string or multiple sources as a list of strings.

If this property is not specified, then any of the other properties are ignored.

See Single vs. Multiple Sources for more information on single vs. multiple sources.
CoalesceSourcesBooleanNoThis property determines how multiple sources are handled. If it is set to true, then all specified sources are coalesced and treated as a single source. If set to false, then the sources are treated individually. If it is omitted, then it is set to False.

See Handling Multiple Sources for information on the affects of coalescing sources.
TransformsList of one or more transformsNoThis property specifies one or more transforms to apply to the sources. Transforms are applied in the order they are specified in this list.

See Transforms for more information on transformations.

📘

CloudZero Defined Dimensions vs User Defined Dimensions

CloudZero defines many useful Dimensions for you in addition to the custom Dimensions you will define in CostFormation. Please note the Sources: syntax difference between CloudZero defined dimensions and your own defined dimensions:

CloudZero defined dimensions: Source: CZ:Defined:<DimensionId>
User defined dimensions: Source: User:Defined:<DimensionId>

📘

Inheriting vs. Overriding Source Properties

It is important to note that source properties are either inherited or overridden as a whole set. Therefore when a rule or a condition inherits a source, it inherits all of the properties, including transforms and whether to coalesce or not. However, if the Source or Sources property is specified in the rule or condition, then all source properties are overridden. If a condition or rule specifies the Source property, but the property Transforms is not specified, the transforms from the outer source are not inherited. In that case, no transforms would be applied to the source specified in the override.

Also, to override the source, the Source or Sources property must be specified. If Transforms is specified but Source or Sources is not, then Transforms is ignored.

Single vs. Multiple Sources

When specifying sources, you can specify either a single source as a string, or multiple sources as a list of strings.

For example:

Source: Account

This specifies the dimension Account as a single source, whereas:

Sources:
  - Tag:Name
  - Resource

specifies Tag:Name and Resources as multiple sources.

📘

Source vs. Sources

The property name Source and Sources are aliases of each other and are completely interchangeable. There is no requirement to use one or the other when specifying a single or multiple sources.

Handling Multiple Sources

When multiple sources are specified you can specify whether they should be coalesced or handled as individual sources. This impacts both how conditions are applied to the sources as well as the element names of dynamic elements when multiple sources are used in GroupBy rules.

📘

Coalescing Sources

Coalescing sources means that the value used will be the value of the first source in the list of sources that has an actual value (i.e. is not null). For example:

  Sources:
    - Tag:Environment
    - Tag:Env
    - Tag:environment

If Tag:Environment has a value, it will be used as the source value and the values in Tag:Env and Tag:environment will be ignored. However, if Tag:Environment did not have a value but Tag:Env did, then the value from Tag:Env would be used. This feature is useful for situations like inconsistent tag names. Like the above example, it allows the three different tags to be treated as a single tag.

How multiple sources are handled is determined by the CoalesceSources property. If omitted or set to False, then the sources are treated individually. Not coalescing multiple sources has two impacts:

  • Any conditions applied to the sources are applied as an Or of the individual sources. For example, the following evaluates to True if either Tag:Name or Resource contains the text development.
- Sources:
    - Tag:Name
    - Resource
  CoalesceSources: False
  Contains: development
  • In a GroupBy rule the dynamic element names will be comprised from concatenating the values from each source. Because each source value is used, all source values must be present for any charge to match the rule. If any one of the sources for a charge does not have a value, then the rule would evaluate to False.

If CoalesceSources is set to True, then the sources are coalesced and treated as a single source, using the first source that has a value. Sources are checked in the order they are specified. Using the example:

- Sources
  - Tag:Name
  - Resource
  CoalesceSources: True
  Contains: development

Any charge checked against the condition, the source value will be the value of Tag:Name, if it is has a value. Otherwise, it will be the value of Resource. Therefore the above example will evaluate to True if the first non-null value of Tag:Name or Resource contains the text development.

The following table shows the differences between applying the condition using the above examples:

Tag:NameResourceResult if CoalesceSource=FalseResult if CoalesceSource=True
frontend-developmentgatewayTrueTrue
frontendgateway-developmentTrueFalse (condition applied to value frontend)
nullgateway-developmentTrueTrue (condition applied to value gateway-development)

Additionally, when CoalesceSources is set to True in a GroupBy rule, the dynamic element names will contain the single coalesced value. Using the table above, the dynamic element names would be: frontend-development, frontend, and gateway-development.

Transforms

When specifying sources, you can optionally specify a list of one or more transformations to apply to the sources. Transforms are ways to modify the source values to do things like lowercase them or extract substrings. Transforms are applied to the sources after coalescing (if coalescing is applied), but before conditions are applied. The result of the transforms is also used when the source data is generating dynamic element names.

Transforms are useful for cleaning your source data before applying conditions or generating dynamic element names to handle problems like inconsistent capitalization or inconsistent use of special characters. They are also useful for extracting substrings out of complex sources for better consistency in applying conditions, or better groupings of dynamic elements.

Transforms have the following structure:

  Transforms:
    - Type: <Transform 1 Name>
      <Transform 1 Parameters>
    - Type: <Transform 2 Name>
      <Transform Parameters>
    ...
    - Type: <Transform N Name>
      <Transform N Parameters>

Transforms are applied in the order they are specified. The input for the first transform is the raw source value, while the input for the second transform would be the result of the first transform, etc. The final value would be the result of the last transform.

For example:

  Transforms:
    - Type: Split
      Delimiter: '-'
      Index: 1
    - Type: Lower

In the above example, the source is split into substrings using the dash (-) character and the first index is taken (the index is 1 based) and the result is then made lowercase. So if the source was Gateway-Development, the result of the transform would be gateway.

See the reference page for the list of available transforms and their parameters.

Adding Rules

Each dimension definition contains a list of one or more CostFormation rules that determine how charges are grouped in elements. Rules tie together sources and conditions to create either statically named elements or dynamically named elements.

Rules are specified as follows:

  <DimensionId>:
    Name: <Name>
    ...
    Rules:
      - Type: <Rule 1 Type>
        <Rule 1 Properties>
      - Type: <Rule 2 Type>
        <Rule 2 Properties>
      ...
      - Type: <Rule N Type>
        <Rule N Properties>

Rule Types

There are three types of rules: Group, GroupBy, and Metdata.

Group Rules

Group rules are used to create statically named elements. These rules are specified as follows:

  - Type: Group
    Name: <Element Name>
    <Source Properties>
    Conditions:
       - <List of conditions>

The properties for a Group rule are:

PropertyTypeRequiredDescription
TypeStringYes (must be set to Group)This property indicates that the rule is a Group rule.
NameStringYesThis property specifies the name of the element.
<Source Properties>Collection of propertiesNoThese properties indicate the default source to use for any conditions within this rule. If not specified, then the source specified for the dimension will be used.

See Specifying Sources for more information.
ConditionsList of conditionsYesThis property specifies a list of one or more conditions that must evaluate to True for charges to be grouped in the specified element.

See Adding Conditions to a Rule for more information.

For example:

  - Type: Group
    Name: Test
    Source: Account
    Conditions:
      - Equals: 123456789010

With this rule any charges where the Account is equal to 123456789010 are placed in the Test element.

GroupBy Rules

GroupBy rules are used to create dynamic elements based on values from the sources. These rules are specified as follows:

  - Type: GroupBy
    Format: <Element Name>
    <Source Properties>
    Conditions:
       <List of conditions>

The properties for a GroupBy rule are:

PropertyTypeRequiredDescription
TypeStringYes (must be set to GroupBy)This property indicates that the rule is a GroupBy rule.
FormatStringNoThis property specifies how to output the source values into dynamic element names. The contents of this property depend on whether the sources are coalesced or not. If not specified the source values will be concatenated with a space between each source.

See the note below on Formatting Elements for more information on how to format element names.
<Source Properties>Collection of propertiesYesThese properties indicate the source to use for generating element names. It will also be used for any conditions within this rule that do not specify a separate source.

The source values must be non-null for charges to match this rule.

See Specifying Sources for more information.
ConditionsList of conditionsNoThis property specifies a list of one or more conditions that must evaluate to True for charges to be grouped in the specified element.

See Adding Conditions to a Rule for more information.

For example:

  - Type: GroupBy
    Format: 'Service {0} -- Region {1}'
    Source:
      - Service
      - Region
    Conditions:
      - Source: Account
        Equals: 123456789010

In this example elements will be created by combining the sources Service and Region using the format string, but only for line items where Account equals 123456789010.

📘

Formatting Elements

When specifying the format for elements in a GroupBy rule, the format string uses zero based indexes to match to the sources. With the example 'Service {0} -- Region {1}', the {0} is replaced with the first source, Service, while {1} is replaced with the second source Region.

The format string must include indexes for each source and only for each source. For example, 'Service {0}' would have been invalid because there is no index for Region while 'Service {0} -- Region {1} -- Country {2}' would be invalid because there is no source to match with {2}.

If the Format property is omitted, the sources are concatenated with a space in-between them. In the above example the default Format would have been '{0} {1}'.

📘

Formatting for Coalesced Sources

If sources are specified to be coalesced, then the format string should only indicate a single index (i.e. {0}). When sources are coalesced, it is the equivalent of specifying a single source.

Metadata Rules

Metadata rules are a type of static grouping rule where the element name and the condition are related. These rules are useful to group elements based on substrings within another dimension such as tags or resource names. When specifying a metadata matching rule, a list of metadata values are provided. The rule will check each of the sources to see if they contain that metadata value or any of its alternatives. When a match is found, the charges are grouped into an element name generated using the specified format and the matching metadata value.

These rules are specified as follows:

  - Type: Metadata
    Format: <Element Name>
    <Source or Sources>
    Conditions:
       <List of conditions>
    Values:
       <List of metadata values>

The properties for a Metadata rule are:

PropertyTypeRequiredDescription
TypeStringYes (must be set to Metadata)This property indicates that the rule is a Metadata rule.
FormatStringNoThis property specifies how to output the metadata values into element names. The format string must be written for a single source and therefore must have one placeholder.

See the note below on Formatting Elements for more information on how to format element names.
<Source or Sources>PropertyYesThese properties indicate a single source or multiple sources to use for the metadata matching. It will also be used for any conditions within this rule that do not specify a separate source.

The source values must be non-null for charges to match this rule.

See Specifying Sources for more information.

Unlike other rules, Transforms are not supported along with these sources.
ConditionsList of conditionsNoThis property specifies a list of one or more conditions that must evaluate to True before the metadata matches are applied.

See Adding Conditions to a Rule for more information.
ValuesList of strings or string and arrays of strings.YesThis property specifies the metadata to match and element names to generate. Charges will be checked to see if the the source contains the metadata value, and if so, it will be grouped in an element named after that metadata value.

For example:

  - Type: Metadata
    Format: 'Metadata Match: {0}'
    Source:
      - Tag:Name
      - Resource
    Conditions:
      - Source: Account
        Equals: 123456789010
    Values:
       - -Web-:
          - -UI-
          - Frontend
       - Order-Processing
       - Order-Staging:
          - WebOrderStaging
       - Order-Fulfillment

In this example, only charges from account 123456789010 will be checked. For all those charges, the Tag:Name and Resource dimensions will be checked to see if they contain any of the specified metadata values in the order they are presented in the Values property. The element names will be generated using the specified format so that there would be elements named Metadata Match: Web, Metadata Match: Order-Processing, Metadata Match: Order-Staging, or Metadata Match: Order-Fulfillment.

📘

Metadata Value Requirements and Element Names

The sources specified for metadata rules are always normalized, which turns any special characters into a dash (-) and uses a case insensitive comparison. Therefore, metadata values may only contain letters, numbers, and dashes (-). If any other character are specified, a validation failure will occur.

Element names generated from the specified metadata values will have their case preserved. Using the above example, a charge with order-staging in Tag:Name will be placed in an element name Metadata Match: Order-Staging.

Any metadata values that contain a leading or trailing dash (-) will only use those characters during matching. The element name will have the leading and/or trailing dash removed.

Using the example above, any charges containing the text -web- will be grouped in the element Metadata Match: Web.

📘

Specifying Alternatives

Sometimes you may want to specify some alternatives to a metadata value. This can be useful when non-uniform tagging has occurred. Alternatives are specified by adding an array of alternatives after the metadata value. If any of those alternatives are found in the source, the charges will be grouped with the first specified metadata value.

Using the example above, the metadata values -Web- and Order-Staging have alternatives specified. Any charges containing either -ui- or frontend will be grouped along with any containing -Web- while charges containing WebOrderStaging will be grouped with any containing Order-Staging.

Applying Rules

Rules are applied in a top-down fashion based on the order the rule is specified. This means that for all charges, the conditions for the first rule in the definition are evaluated before the second rule, etc. Therefore, the order that rules appear in your definitions is very important and can affect how charges are broken down into elements.

Using the following example:

  Environment:
    Name: Environment
    Source: Account
    Rules:
      - Type: Group
        Name: Alfa
        Conditions:
          - Equals: 123456789010
      - Type: Group
        Name: R&D
        Conditions:
          - Source: CZ:Defined:Category
            Equals: Cloud Management
          - Source: Service
            Contains: Support
      - Type: Group
        Name: Production
        Conditions:
          - Equals:
            - 123456789011
            - 123456789012
          - And:
            - Equals: snowflake1234
            - Source: ProductFamily
              Equals: warehouse
            - Source: Resource
              Contains: prod
          - And:
            - Equals: snowflake1234
            - Source: ProductFamily
              Equals: database
            - Source: Resource
              Equals: live_billing

The conditions of the first rule (Name: Alfa) are checked before the conditions for the second rule (Name: R&D). Using these rules, all charges where the Account is equal to 123456789010 are placed in the Alfa element. For any charge whose Account is not equal to 123456789010 the charge will next be checked to see if CZ:Defined:Category is equal to Cloud Management or Service contains Support.

If all rules evaluate to False, then the charge will be grouped with other charges that do not match any rules. If a DefaultValue is specified, then the charges are grouped under that element. Otherwise they will be considered unallocated and will not be considered part of this dimension.

📘

DefaultValue vs. Unallocated

When charges do not match any rule, there is a distinct difference between having a DefaultValue property for a dimension or not. When no DefaultValue is specified all charges not matching any rules are considered unallocated. However, if DefaultValue is specified, then all charges not matching any rule will be placed in the element defined by `DefaultValue'.

When filtering in the explorer, if you choose to filter all charges where the dimension Does Not Have a Value, it will only show unallocated charges. If a DefaultValue was specified, those charges are considered allocated (to the element named in DefaultValue) and therefore would not show up when this filter is applied.

📘

Combining Rule Types

When creating a Custom Dimension definition, you can combine rule types in ways that some elements are statically defined while others are dynamically defined. Consider the environment dimension example from before. Perhaps there are some resources that are not in any of the defined accounts, but are tagged with a special environment tag. You could define the dimension as follows:

  Environment:
    Name: Environment
    Source: Account
    Rules:
      - Type: Group
        Name: Alfa
        Conditions:
          - Equals: 123456789010
      - Type: Group
        Name: R&D
        Conditions:
          - Source: CZ:Defined:Category
            Equals: Cloud Management
          - Source: Service
            Contains: Support
      - Type: Group
        Name: Production
        Conditions:
          - Equals:
            - 123456789011
            - 123456789012
          - And:
            - Equals: snowflake1234
            - Source: ProductFamily
              Equals: warehouse
            - Source: Resource
              Contains: prod
          - And:
            - Equals: snowflake1234
            - Source: ProductFamily
              Equals: database
            - Source: Resource
              Equals: live_billing
      - Type: GroupBy
        Source: Tag:Environment

In the above definition, the addition of the last GroupBy rule will capture any charges that did not match the previous rules and check if the associated resource has a value in the Tag:Environment. For those charges that have a value in Tag:Environment it will create elements based on the values in that tag. If the tag values include the values: Alfa, R&D, or Production, those charges will be grouped into the same element as the ones defined with the Group rule.

Adding Conditions to a Rule

Conditions are the logic operations that are applied to sources to determine whether a charge should be included in a given rule. Conditions are structured as follows:

  Conditions:
    - <Condition 1 Name>: <Condition 1 Values>
    - <Condition 2 Name>: <Condition 2 Values>
    ...
    - <Condition N Name>: <Condition N Values>

Condition Types

There are a few different types of conditions which allow you to compare source values against one or move values, compare whether sources have a value or not, or perform a logical operation that combines other conditions in a logical And or Or to create more complex conditions. Each condition type has a different structure.

String Comparison Operations

String Comparison operations compare the source value against one or more provided values. They are used to evaluate things like if a given source equals one or more values or if a source contains one or more values as a substring.

Comparison can take either a single value. They use one of the following structures:

  - <Condition Name>: <Value>
    <Source Properties>

Or:

  - <Condition Name>:
      - <Value 1>
      - <Value 2>
      ...
      - <Value N>
    <Source Properties>
PropertyTypeRequiredDescription
<Condition Name>String or list of stringsYesThis specifies the name of the condition to apply. It must be one of the following: BeginsWith, Contains, or Equals.

If a single string specified, then the source is compared against this single value. Otherwise, if a list is specified, then the condition is applied to each value as an Or in the order the values are specified. For example if the condition is Equals then it will evaluate to true if the source equals any one of the specified values.
<Source Properties>Collection of propertiesNoIf specified, the condition will be applied to the specified sources along with any coalescing and/or transforms specified. If not specified, then the source from either the enclosing rule or dimension definition will be used.

See Specifying Sources for more information.

HasValue Condition

The HasValue condition allows you to evaluate whether a source is has an actual value or is null. It has the following structure:

  - HasValue: <True|False>
    <Source Properties>
PropertyTypeRequiredDesccription
HasValueBooleanYesThis applies the HasValue operation to the source. If it is set to True, then the condition evaluates to True if the source has a value. If set to False then the condition evaluates to True if the source does not have a value.
<Source Properties>Collection of propertiesNoIf specified, the condition will be applied to the specified sources along with any coalescing and/or transforms specified. If not specified, then the source from either the enclosing rule or dimension definition will be used.

See Specifying Sources for more information.

Boolean Logic Operations

There are three Boolean logic operations that can be applied in conditions: And, Or, and Not. Each of these operations has the following format:

  - <Logical Operator>
    - <Condition 1>
    - <Condition 2>
    ...
    - <Condition N>

The logical operations are applied as follows:

OperationDescription
AndAll of the conditions in the list must evaluate to True for this condition to evaluate to True. If even one condition evaluates to False, then the whole condition evaluates to False.
OrOnly one condition in the list must evaluate to True for the entire condition to evaluate to True. Only when all conditions evaluate to False will the whole condition evaluate to False.
NotThe list of conditions are evaluated like an Or, but the final result is reversed. So if a single condition evaluates to True, then the whole condition evaluates to False. This condition only evaluates to True if all conditions in the list evaluate to False.

Logical operation can be nested. For example:

  - And:
    - Or:
      - <condition 1>
      - <condition 2>
    - Not:
      - And:
        - <condition 3>
        - <condition 4>

This condition will evaluate to True only if either condition 1 or condition 2 is True and either condition 3 or condition 4 are False.

Applying Conditions

As with rules, the order conditions are listed is important as conditions are evaluated top-down in the order presented in the list. If the first condition of a rule evaluates to True, then the whole condition evaluates to True and remaining conditions are not evaluated. If the first condition evaluates to False then second condition will be evaluated, etc. If all conditions within a rule evaluate to False, then the rule itself evaluates to False. This effectively means that all of the conditions in a list are evaluated as a logical Or with the exception of when the list is part of the And logical operation.

See the reference page for the list of available conditions and their parameters.

Adding Allocations

Allocation rules are used for an Allocation Dimension and define how shared resource costs should be split. They are defined under the AllocateByStreams key.

Streams

An explicit allocation must be composed of a list of telemetry streams. The syntax is as follows:

Dimensions:
  Customer:
    Type: Allocation
    Name: Cost per Customer
    Hide: False
    Disable: False
    AllocateByStreams:
    Streams:
      - widget-processing-time
      - another-stream
      - active-organizations

A telemetry stream is comprised of utilization data sent by a customer organization to CloudZero. This data allows shared resource costs to be de-aggregated and precisely allocated. For more information on creating telemetry streams see the CostFormation: Allocating Shared Costs and Unit Cost Analytics documentation.

Streams are listed in priority order and it is perfectly fine and expected that stream targets within a dimension will overlap at times. If a particular resource is targeted by multiple streams for the same time period, the higher priority stream will take precedence.

Priority order is determined top to bottom, with the first stream taking highest priority. In the above example, widget-processing-time is the highest priority stream, while active-organizations is the lowest.

Prerequisites

A stream must already exist within CloudZero in order to be used in a dimension definition. A list of available telemetry streams can be viewed within the application.

Restrictions

In order to enforce best practices and prevent overly complex definitions that could impair your experience, there are several restrictions that CloudZero has applied when authoring dimensions. Each restriction has a threshold that can be adjusted by your customer success team.

There are three areas of restriction:

  • The number of streams used within a single dimension definition
  • The number of Allocation Dimensions that can be combined as sources
  • The number of dimensions that can combine the Resource Dimension and Allocation Dimensions as sources

Publishing an edit that violates one or more restrictions will result in a validation error along with a helpful error message.


What’s Next

Learn how to use short form rules: