The Iteration Pattern
The
origin_resourceFor-Each Loop and Anatomy of a Configuration File
The most important concept for writing model files is rescile’s implicit iteration pattern. Think of each
.toml configuration file as a module that contains a loop.
The Golden Rule: A configuration file with
origin_resource = "application"is afor-eachloop. It tellsrescileto run the rules in that file once for everyapplicationin your graph.
You don’t write imperative loops — you declare a set of rules that operate on a collection of resources. rescile
handles the iteration automatically.
Declarative vs. Imperative
The declarative model file below is equivalent to the imperative pseudo-code that follows it.
# data/models/server.toml
origin_resource = "application"
[[create_resource]]
resource_type = "server"
relation_type = "HOSTED_ON"
name = "{{ origin_resource.name }}_server"
[[create_resource]]
match_on = [{ property = "environment", value = "prod" }]
resource_type = "monitoring_agent"
name = "agent_for_{{ origin_resource.name }}"
all_applications = graph.find_resources(type="application")
for current_application in all_applications:
create_server_for(current_application)
if current_application.environment == "prod":
create_monitoring_agent_for(current_application)
Data-Driven Iteration with create_from
As an alternative to iterating over graph resources, rescile supports a data-driven iteration model using the
create_from directive. This lets you generate resources from an abstract list defined in the file header.
# data/models/providers.toml
# No origin_resource is defined.
providers = { "json!" = "shared/providers.json" }
provider_list = { "template!" = '''{{ providers | map(attribute="name") | safe }}''' }
[[create_resource]]
create_from = { list = "provider_list", as = "provider" }
name = "ext-{{ value }}"
In this mode the origin_resource variable is unavailable; instead the special value variable holds the current
item from the list.
Anatomy of a Configuration File
Every rescile .toml file has two sections: a Header and one or more Rule Blocks.
# ── HEADER ──────────────────────────────────────────────────────────────
origin_resource = "application" # The for-each subject
# File-scoped data available to all Rule Blocks
server_specs = { standard_cpu = 4, premium_cpu = 8 }
ip_ranges = { "json!" = "shared/ip_ranges.json" }
# ── RULE BLOCK 1 ─────────────────────────────────────────────────────────
[[create_resource]]
resource_type = "server"
relation_type = "HOSTS"
name = "server_{{ origin_resource.name }}"
[create_resource.properties]
cpu_cores = "{{ server_specs.standard_cpu }}"
status = "provisioning"
# ── RULE BLOCK 2 ─────────────────────────────────────────────────────────
[[create_resource]]
match_on = [{ property = "environment", value = "prod" }]
resource_type = "monitoring_agent"
name = "agent_{{ origin_resource.name }}"
Header (Module Scope)
| Key | Description |
|---|---|
origin_resource |
Optional. The resource type this file iterates over. If omitted, rules run once in a global context (useful for singletons or create_from generation). |
| Any other key | File-scoped data available as template variables. May be an inline TOML table, a { "json!" = "..." } reference, or a { "template!" = "..." } or { "function!" = "..." } snippet. |
When
origin_resourceis omitted, rules are processed exactly once unlesscreate_fromwith alistis used. Theorigin_resourcevariable is not available in templates.
Rule Blocks and Directives
A Rule Block is a TOML array-of-tables entry such as [[create_resource]] or [[link_resources]]. Think of
each block as a single executable function that rescile evaluates for every iteration of the loop.
Inside a Rule Block, Directives are the key-value pairs that configure the function — for example
resource_type, name, relation_type, and match_on.
Global Context: Module Parameters
In addition to the file-scoped data defined in the header, any module parameters passed via --module-params
on the command line are available as global variables in every template across all files in the module.
rescile-ce --module ./my-module --module-params "region=eu-central-1;env=prod" serve
Inside any template: {{ region }} renders "eu-central-1" and {{ env }} renders "prod".
For the complete reference on all available template data and functions, see Tera Essentials.