Architectural Models
Transforming Raw Assets into a Rich Dependency Graph
While Assets provide the raw data, the Model Engine is where you define the architecture. Models are declarative blueprints in TOML that transform asset data into a rich, contextual dependency graph. Each model file, located in data/models/, typically introduces a new type of resource by deriving it from an existing one.
It does not matter if an origin resource was created directly from an asset or generated by another model. The engine treats all resources equally. This makes models highly versatile and is especially relevant for reusable modules: a module can be used stand-alone by starting directly from its own assets, or it can be integrated into a larger graph where its required starting resources are seamlessly provided by other models.
This section covers the primary directives for building your architectural graph:
- Creating Resources: Using
[[create_resource]]to derive new nodes from existing assets or data. - Propagating Data: Using
[[copy_property]]to push data along existing relationships. - Linking Resources: Using
[[link_resources]]to join disparate resources and pull data from them. - Templating Essentials: Leveraging templates and dynamic data in model files.
- Graph Behavior: Idempotency, merging, and automatic relationship creation.
The Anatomy of a Model File: Header and Rule Blocks
A model file consists of two main parts: the Header (defining the file’s scope and data) and one or more Rule Blocks (the executable instructions).
The header provides a rich context of data that you can access within your templates, allowing for highly dynamic configurations. This data comes from several sources:
# data/models/server.toml
# --- HEADER ---
# 1. `origin_resource`: The subject for the file's for-each loop.
# This model will execute its Rule Blocks once for every "application" resource.
origin_resource = "application"
# 2. File-Scoped Data: Available to all templates in this file.
server_specs = { standard_cpu = 4, large_cpu = 8 }
network_data = { "json!" = "data/networks.json" }
server_name_prefix = { "function!" = "srv-{{ origin_resource.environment }}-" }
# --- RULE BLOCKS ---
[[create_resource]]
# ... directives for this rule block ...
| Key | Description |
|---|---|
origin_resource |
Optional. The resource type this model’s Rule Blocks will iterate over. If omitted, rules execute in a global context, which is useful for creating singleton resources or for data-driven generation with the create_from directive. |
(any name) |
Optional. Any other top-level key is treated as file-scoped data available to templates. Standard template strings (e.g. "{{ ... }}") are evaluated globally across all matching resources. To evaluate a template per-iteration (accessing the single origin_resource), use { "template!" = "..." } or { "function!" = "..." }. Other options include an inline TOML table (like server_specs), or a reference to an external JSON file using { "json!" = "path/to/file.json" }. |
This data is then accessible within templates inside your Rule Blocks, for example: {{ origin_resource.name }}, {{ server_specs.standard_cpu }}, or {{ network_data.subnets.prod }}. server_name_prefix is defined as function! it is used like a function inside the rule block.