Skip to main content
Skip table of contents

Generation Rules

Introduction

Generation Rules help the RunWhen Workspace Builder determine which CodeBundles (and thus which SLXs) should be included in a workspace, based on the resources the Workspace Builder discovers on configured cloud platforms (e.g. Kubernetes, Azure, GCP).

When you run the Workspace Builder:

  1. It loads the generation rules defined in your CodeBundles (which are defined/enabled in your workspace info file).

  2. It indexes resources from your configured cloud platforms and stores them in a simple in-memory database.

  3. It evaluates the generation rules to see which resources match certain criteria.

  4. For each matching rule, it generates one or more SLX files in the final workspace directory structure.

This document explains the format of those generation rules and how they work. It’s particularly helpful if you’re creating or modifying CodeCollections.


Directory Structure

Each CodeBundle can include an optional folder named .runwhen that stores:

  • generation-rules/: All the YAML files that define your match logic and what SLXs to create.

  • templates/: Jinja2-based files used to render the actual content (YAML) of the SLXs when a rule matches.

For example:

CODE
k8s-namespace-healthcheck
└── .runwhen
    ├── generation-rules
    │   └── k8s-namespace-healthcheck.yaml
    └── templates
        ├── k8s-namespace-healthcheck-sli.yaml
        ├── k8s-namespace-healthcheck-slo.yaml
        ├── k8s-namespace-healthcheck-slx.yaml
        ├── k8s-namespace-healthcheck-taskset.yaml
        └── k8s-namespace-healthcheck-workflow.yaml

Generation Rule YAML File

A generation rules file can contain one or more rules. Its general structure looks like:

CODE
apiVersion: runwhen.com/v1
kind: GenerationRules
spec:
  platform: <target-platform>   # e.g. 'kubernetes', 'azure', or 'gcp'
  generationRules:
  - resourceTypes:
      - <resource-type-name>    # e.g. 'k8s.core.v1.pods' or 'azure_compute_instances'
    matchRules:
      - # (list of match predicates)
    slxs:
      - # (SLX generation settings)

Supported Platforms

  • kubernetes

  • azure

  • gcp

If no platform is specified, it defaults to Kubernetes.


Resource Types

Each rule checks specific resource types in that platform. For example, if the rule’s resourceTypes is [ "k8s.core.v1.pods" ], the Workspace Builder will index all Kubernetes Pods and evaluate the match predicates against each Pod. For Azure or GCP, the resource types typically match CloudQuery table names, or recognized aliases if available.


Platform-Specific Fields

When writing your matchRules or building Jinja2 templates, you can leverage the following built-in fields for each platform:

Kubernetes

  • name: Name of the resource

  • labels: All label keys and values

  • label-keys: Just the label keys

  • label-values: Just the label values

  • annotations: All annotation keys and values

  • annotation-keys: Just the annotation keys

  • annotation-values: Just the annotation values

  • namespace: The parent Kubernetes namespace

  • cluster: The parent Kubernetes cluster

Azure

  • name: Name of the resource

  • tags: All tag keys and values

  • tag-keys: Just the tag keys

  • tag-values: Just the tag values

  • resource_group: The parent resource group

GCP

  • name: Name of the resource

  • project: The parent project ID

You can also specify custom paths into the raw resource data (e.g., spec/region). If the path encounters a list, it will check each element of that list for a match.


Match Rules

A match rule is how you decide if a particular resource “matches” your conditions. There are two main leaf-level predicates and three ways to combine them:

1) Pattern Predicate

This checks if a property of the resource matches a certain text pattern (regex). Example:

CODE
type: pattern
properties:
  - name           # could also be a path like 'metadata.name'
pattern: "^prod-.*"  # python-style regex
mode: exact          # or 'substring' (default)

Fields:

  • type: "pattern"

  • resourceType: Optional; override top-level resource types.

  • properties: A list of resource properties to match against (e.g. name, labels, tags, annotation-values, or a raw path like spec/region).

  • pattern: A Python-style regex.

  • mode: "exact" or "substring" (substring is default).

2) Exists Predicate

Checks if a property exists at all:

CODE
type: exists
properties:
  - annotation-keys

Fields:

  • type: "exists"

  • Same property syntax as pattern predicates.

  • No pattern or mode fields (because it just checks for existence).

Compound Boolean Predicates

You can combine predicates using and, or, and not:

CODE
type: and
matches:
  - type: pattern
    properties:
      - name
    pattern: "^production-.*"
  - type: pattern
    properties:
      - namespace
    pattern: "^prod-namespace"
  • type: and: All child predicates must match.

  • type: or: At least one child predicate must match.

  • type: not: Child predicate must not match.


Example: A Simple Kubernetes Match Rule

CODE
spec:
  platform: kubernetes
  generationRules:
    - resourceTypes:
        - "k8s.core.v1.namespaces"
      matchRules:
        - type: and
          matches:
            - type: pattern
              properties: [ "name" ]
              pattern: "^prod-.*"
              mode: exact
      slxs:
        - base_name: "namespace-healthcheck"
          qualifiers:
            - cluster
            - namespace
          base_template_name: "k8s-namespace-healthcheck"
          level_of_detail: "basic"
          output_items:
            - type: slx
            - type: sli
            - type: slo
            - type: runbook

Explanation:

  1. This rule targets Kubernetes namespaces (resourceTypes: ["k8s.core.v1.namespaces"]).

  2. It matches any namespace whose name starts with "prod-".

  3. For each match, it will generate multiple SLX files (slx, sli, slo, runbook), all based on the "k8s-namespace-healthcheck" templates.

  4. The SLX’s full name includes namespace-healthcheck and the resource’s cluster and namespace as qualifiers.


SLX Generation (the slxs section)

Once a resource matches, one or more SLX files can be created. Each entry in slxs defines how to build those files.

CODE
slxs:
  - base_name: "namespace-healthcheck"
    qualifiers:
      - namespace
    shortened_base_name: "ns-healthchk"   # (optional override if you need a custom shortened name)
    level_of_detail: "basic"              # or "detailed"
    base_template_name: "k8s-namespace-healthcheck"
    output_items:
      - type: slx
      - type: sli
        level_of_detail: "detailed"       # override the parent detail level
      - type: runbook
        template_name: "my-custom-runbook.yaml"
        template_variables:
          custom_var: "{{match_resource.name | upper}}"

Key Fields:

  • base_name: The main identifier.

  • qualifiers: Attributes from the matched resource to make the name unique (e.g. resource, namespace, cluster, etc.).

  • shortened_base_name: Override if the automatic name-shortening is too cryptic. Should be <= 15 characters.

  • level_of_detail: "basic" or "detailed".

  • base_template_name: Default prefix for your template files.

  • output_items: Array of SLX file types to emit. Each can have:

    • type: The SLX type (e.g. slx, sli, slo, or runbook).

    • path: (Optional) The file path in your workspace. Defaults to slx.yaml, sli.yaml, etc.

    • template_name: (Optional) If you don’t want to follow the default naming scheme, specify a custom template file.

    • template_variables: (Optional) Additional Jinja2 variables to pass in.

    • level_of_detail: (Optional) Override for that specific file.


SLX Template Files

The .runwhen/templates/ folder contains one or more Jinja2 templates for each SLX output. They often start with some boilerplate like:

CODE
apiVersion: runwhen.com/v1
kind: ServiceLevelX
metadata:
  name: {{ slx_name }}
  labels:
    {% include "common-labels.yaml" %}
  annotations:
    {% include "common-annotations.yaml" %}
spec:
  # your custom content here, can use Jinja2 variables
  myField: {{ match_resource.name }}

Available Template Variables

Here are some of the most common variables you can use in your templates:

  • workspace: The name of the parent workspace.

  • slx_name / full_slx_name: Shortened vs. unshortened SLX name.

  • base_name: The original base_name from the generation rule.

  • match_resource: The resource object that matched.

    • You can do {{ match_resource.resource.some_field }} to reference raw data from the resource.

  • namespace, cluster, resource_group, project: The parent scoping data for each platform (K8s, Azure, GCP).

  • custom: Maps to the custom field in the workspace info file (if any).

Tip: If you’re not sure which fields are available in match_resource.resource, you can consult the CloudQuery plugin docs or look at the automatically generated resource-dump.yaml file in the shared directory. That file shows all resources the Workspace Builder discovered, which helps you figure out the field paths you might want to match against or print in the templates.


Putting It All Together: An Azure Example

Directory Layout:

CODE
azure-vm-observability
└── .runwhen
    ├── generation-rules
    │   └── azure-vm-observability.yaml
    └── templates
        ├── azure-vm-observability-slx.yaml
        ├── azure-vm-observability-sli.yaml
        └── azure-vm-observability-runbook.yaml

Generation Rule (azure-vm-observability.yaml):

CODE
apiVersion: runwhen.com/v1
kind: GenerationRules
spec:
  platform: azure
  generationRules:
    - resourceTypes:
        - "azure_compute_instances"  # CloudQuery table name for Azure VMs
      matchRules:
        - type: pattern
          properties: [ "tags", "resource_group" ]
          pattern: "critical|high-priority"
          mode: substring
      slxs:
        - base_name: "azure-vm-observability"
          qualifiers:
            - resource_group
            - resource
          base_template_name: "azure-vm-observability"
          level_of_detail: "basic"
          output_items:
            - type: slx
            - type: sli
            - type: runbook

Here we:

  1. Target Azure VMs (azure_compute_instances).

  2. Match any VM whose tags or resource group contains "critical" or "high-priority".

  3. For each match, generate an SLX file, an SLI file, and a runbook, all using templates that start with azure-vm-observability-*.

Sample Template (azure-vm-observability-slx.yaml):

CODE
apiVersion: runwhen.com/v1
kind: ServiceLevelX
metadata:
  name: {{ slx_name }}
  labels:
    {% include "common-labels.yaml" %}
  annotations:
    {% include "common-annotations.yaml" %}
spec:
  description: "Observability SLX for Azure VM: {{ match_resource.name }}"
  location: {{ default_location }}
  ...

Summary

  • Generation Rules help you dynamically generate SLXs (and related files) for specific cloud resources.

  • matchRules define how to identify those resources.

  • slxs define which files get generated and how they are named.

  • Templates (using Jinja2) allow you to customize the final YAML content of each SLX.

Use this reference when you’re writing or modifying CodeCollections that define new SLX rules, or when you need to understand why certain SLXs are being generated in your workspace.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.