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:
Whilematch_onalways filters theorigin_resource(the subject of the current iteration), thematch_withdirective 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.csvname,environment,domain billing-api,prod,example.com auth-service,dev,example.comResult: Two
applicationresources are created. -
data/assets/domain.csvname,owner example.com,ops-teamResult: One
domainresource is created.rescile’s auto-relation feature sees that thedomaincolumn inapplication.csvmatches thedomainresource type and automatically creates relationships:(application) -> (domain).
Phase 2: Models
data/models/server.tomlorigin_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:
rescilebegins processingserver.toml.- It fetches the first
application:billing-api. This application is linked to thedomainnamedexample.com, which hasowner: "ops-team". - Iteration 1:
billing-api- It evaluates the first
[[create_resource]]block.- A
serverresource namedbilling-api_serveris created withenvironment: "prod". - A
HOSTSrelationship is created:(application:billing-api) -> (server:billing-api_server).
- A
- It evaluates the second
[[create_resource]]block.- It evaluates the
match_onconditiondomain.owner == "ops-team". resciletraverses frombilling-apito theexample.comdomain and checks itsownerproperty. The value isops-team, so the condition is true.- A
firewall_ruleresource namedfw_rule_for_billing-apiis created. - A
NEEDSrelationship is created:(application:billing-api) -> (firewall_rule:fw_rule_for_billing-api).
- It evaluates the
- It evaluates the first
- It fetches the second
application:auth-service. This application is also linked to theexample.comdomain. - Iteration 2:
auth-service- It evaluates the first
[[create_resource]]block.- A
serverresource namedauth-service_serveris created withenvironment: "dev". - A
HOSTSrelationship is created:(application:auth-service) -> (server:auth-service_server).
- A
- It evaluates the second
[[create_resource]]block.- The
match_onconditiondomain.owner == "ops-team"is checked again. The traversal is performed, and the condition is true. - A
firewall_ruleresource namedfw_rule_for_auth-serviceis created.
- The
- It evaluates the first