Architectural Models

Convention-Based Creation

How to use create_from to generate resources from property values or abstract data lists in the header.

Convention-Based Creation (create_from)

Generating Resources from Property Values and Data Lists

The create_from directive inside a [[create_resource]] block provides two powerful convention-over-configuration patterns for resource creation.

  • create_from = { property = "..." } — creates resources from the values of a property on the origin_resource
  • create_from = { list = "..." } — creates resources by iterating over an abstract data list defined in the header

Both patterns make the iterated item available as {{ value }} inside templates.


Pattern 1: Creating from a Property Value

When a property contains a list (an array or a comma-separated string), create_from creates one resource for each item. The property name becomes the default resource type, and the property value becomes the default primary key (name). Both can be overridden.

data/assets/application.csv

name,service
zabbix,"monitoring, alerting"

data/models/application_services.toml

origin_resource = "application"

[[create_resource]]
create_from = { property = "service" }
relation_type = "PROVIDES"
name = "svc-{{ value | upper }}"
[create_resource.properties]
category = "Operations"

Result: Two service resources are created — svc-MONITORING and svc-ALERTING — each linked to the zabbix application via a PROVIDES relationship.

Template Variables Available in create_from

Inside the [[create_resource]] block during a create_from = { property = "..." } expansion, the template context contains:

Variable Type Description
value String The current element value (e.g. "monitoring").
property.value String Alias for value.
property.index Integer 0-based iteration index (0, 1, 2, …). Useful for array indexing, naming, and procedural calls.
origin_resource Map Properties of the origin resource currently being expanded.
origin_resource_counter Integer Counter incrementing once per origin resource processed.

Note: Tera’s built-in loop.index / loop.index0 variables are not present in create_from iterations. The iteration is handled directly by the rescile importer engine, which provides property.index. For per-origin CIDR splits, select the matching subnet inside properties, for example {{ origin_resource.cidr | lib(path="network.rhai", function="cidr_split_n", n=4) | nth(n=property.index) }}. Test with two origins that have different CIDRs; a shared top-level value would give both the same plan.

Type Resolution Priority

The resource type for items created by create_from is resolved in this order (highest priority first):

  1. The as key inside the create_from block: create_from = { property = "service", as = "platform_service" }
  2. The top-level resource_type directive
  3. The property name itself (e.g., "service")

Use property_origin to read the source property from a related node instead of the origin_resource. Use relation_origin to control where the new relationship starts from.

Goal: From a subscription, find its related application, read its service property, and create service resources linked back to the subscription (not the application).

origin_resource = "subscription"

[[create_resource]]
property_origin = "application"           # Read the property from the related application
create_from = { property = "service" }
relation_type = "USES"
relation_origin = "origin_resource"       # Start the new relation from the subscription

Important: For property_origin to find the related resource, the referencing column on the origin_resource must remain a plain string property. If the column name matches a resource type/asset filename (such as application), the asset importer will auto-link it and remove the scalar property. In that case, prefix the header with _ (e.g., _application) to suppress auto-linking while keeping the value readable.

property_origin currently follows a single relationship and, if the property contains multiple values, only uses the first one.


Pattern 2: Creating from a Data List

When used with list, create_from iterates over a variable defined in the file header. A normal literal or globally resolved list is ideal for bootstrapping a graph from configuration data rather than from existing graph resources. No origin_resource is needed or available during that global list iteration.

# data/models/providers.toml
# No origin_resource is defined.

provider_list = ["aws", "azure", "gcp"]

[[create_resource]]
create_from = { list = "provider_list", as = "provider" }
name = "cloud-{{ value }}"
[create_resource.properties]
short_name = "{{ value | upper }}"
category = "IaaS"

Result: Three provider resources are created: cloud-aws, cloud-azure, and cloud-gcp.

Origin-dependent dynamic JSON lists

When the header list is a templated json! binding that transitively depends on origin_resource, rescile infers a nested iteration. It resolves the selected file separately for each origin, then exposes each list item as value while keeping the current origin_resource available:

origin_resource = "compute"

environment_name = { "function!" = "{{ origin_resource.environment | lower }}" }
providers = { "json!" = "{{ environment_name }}-providers.json", jmespath = "providers" }

[[create_resource]]
create_from = { list = "providers" }
resource_type = "login"
relation_type = "USES_PROVIDER"
name = "{{ origin_resource.name }}-{{ value.name }}-login"

The JSON path may use global values such as params instead. In that case rescile resolves the list once and keeps the normal global list behavior. The path cannot depend on value, because rescile must load the list before the first value exists.


Comparison of Creation Patterns

Feature Direct Derivation From Property From Global List From Origin-Dependent JSON List
Trigger Existence of a graph resource Values inside an origin property A globally resolved header list A dynamic header list selected by each origin
origin_resource available? Yes Yes No Yes
value available? No Yes Yes Yes
Cardinality 1:1 1:N per origin N resources 1:N per origin
Default resource type resource_type (required) Property name List name List name
Default name name template (required) Property value List item value List item value
Primary use case Structural relationships Dependencies stored on the graph Bootstrapping from global configuration Per-origin local lookup data

For the full [[create_resource]] directive reference, see [[create_resource]] Reference.