Architectural Models

Conditional Logic with match_on and match_with

How match_on and match_with filters resources by property value and traverses relations for context-aware rule evaluation.

Conditional Logic with match_on and match_with

Filtering and Traversing the Graph

The match_on directive allows you to apply rules selectively, filtering which resources are processed. The most common use is a simple property check:

# Only applies if the resource has a property `environment` with the value `prod`.
match_on = [{ property = "environment", value = "prod" }]

When to use match_with:
While match_on always filters the origin_resource (the subject of the current iteration), the match_with directive is its exact counterpart used exclusively in [[link_resources]] rules to filter the candidate target (with) resource set. Both directives share the exact same syntax and capabilities.

A more powerful feature is the ability to match on properties of related resources using dot notation.

# Applies if the resource is linked to a `domain` resource whose `owner` is `ops-team`.
match_on = [{ property = "domain.owner", value = "ops-team" }]

When rescile evaluates this rule, it traverses from the current origin_resource along the domain relationship to the connected domain resource(s). It then checks the owner property on those resources. If the domain property on the origin resource contains an array of related domains, the condition is considered true if any one of them matches the criteria.

This traversal capability is essential for creating context-aware rules that depend on the wider state of your graph, not just the properties of a single resource.

A Concrete Walkthrough

Let’s trace the process with a more detailed example that uses relationship traversal.

Phase 1: Assets

  • data/assets/application.csv

    name,environment,domain
    billing-api,prod,example.com
    auth-service,dev,example.com
    

    Result: Two application resources are created.

  • data/assets/domain.csv

    name,owner
    example.com,ops-team
    

    Result: One domain resource is created. rescile’s auto-relation feature sees that the domain column in application.csv matches the domain resource type and automatically creates relationships: (application) -> (domain).

Phase 2: Models

  • data/models/server.toml
    origin_resource = "application"
    
    [[create_resource]]
    resource_type = "server"
    relation_type = "HOSTS"
    name = "{{ origin_resource.name }}_server"
    [create_resource.properties]
    environment = "{{ origin_resource.environment }}"
    
    [[create_resource]]
    # This rule now checks a property on the related domain.
    match_on = [{ property = "domain.owner", value = "ops-team" }]
    resource_type = "firewall_rule"
    relation_type = "NEEDS"
    name = "fw_rule_for_{{ origin_resource.name }}"
    

Processing Walkthrough:

  1. rescile begins processing server.toml.
  2. It fetches the first application: billing-api. This application is linked to the domain named example.com, which has owner: "ops-team".
  3. Iteration 1: billing-api
    • It evaluates the first [[create_resource]] block.
      • A server resource named billing-api_server is created with environment: "prod".
      • A HOSTS relationship is created: (application:billing-api) -> (server:billing-api_server).
    • It evaluates the second [[create_resource]] block.
      • It evaluates the match_on condition domain.owner == "ops-team".
      • rescile traverses from billing-api to the example.com domain and checks its owner property. The value is ops-team, so the condition is true.
      • A firewall_rule resource named fw_rule_for_billing-api is created.
      • A NEEDS relationship is created: (application:billing-api) -> (firewall_rule:fw_rule_for_billing-api).
  4. It fetches the second application: auth-service. This application is also linked to the example.com domain.
  5. Iteration 2: auth-service
    • It evaluates the first [[create_resource]] block.
      • A server resource named auth-service_server is created with environment: "dev".
      • A HOSTS relationship is created: (application:auth-service) -> (server:auth-service_server).
    • It evaluates the second [[create_resource]] block.
      • The match_on condition domain.owner == "ops-team" is checked again. The traversal is performed, and the condition is true.
      • A firewall_rule resource named fw_rule_for_auth-service is created.