Documentation

Output Engine

Generate structured data artifacts like reports, manifests, and configuration files from your fully constructed graph using Tera templates or Jsonnet.

Air-Gap Ready Self-Hosted Open Ecosystem

Output

Turning Your Graph into Actionable Artifacts

Output files, located in data/output/, are the final step in the processing pipeline. They query the fully constructed, compliance-enriched graph and generate new, structured data resources. This is ideal for creating artifacts like Terraform variable files, Kubernetes manifests, compliance summaries, service catalogs, or inputs for other automation systems.

Similar to models, an [[output]] rule iterates over each matching origin_resource and creates one new resource per match. Unlike models, which enrich the graph with structural components, outputs are designed to generate final, structured data artifacts from the fully built graph. This can include downloadable files like reports or manifests.

Processing order: Output files are processed last, after Asset Loading, Model Application, and Compliance Application. This guarantees that every output template sees the fully governed, enriched graph. See The Processing Model for the complete pipeline diagram.


File Header & Rule Structure

Key Scope Mandatory Description
origin_resource Top Level Yes The resource type to iterate over (e.g., application).
(any name) Top Level No Custom data for use in templates, such as { "json!" = "path/to/file.json" }.
[[output]] Top Level Yes An array of rules, each defining an aggregate output resource to generate.

Each [[output]] block defines a rule for creating a single aggregate resource.

Key Scope Mandatory Description
resource_type [[output]] Yes The type for the new output resource created for each matching origin_resource.
name [[output]] Yes A template for the primary key (name property) of the new output resource. It is rendered once for each matching origin_resource.
match_on [[output]] No An array of filter objects. The rule is applied only if the origin_resource matches all conditions.
filename [[output]] No A template for the filename when the output is downloaded via the API. If present along with mimetype, this enables a download endpoint for the resource.
mimetype [[output]] No The MIME type for the output content (e.g., application/json, text/csv). If present along with filename, this enables a download endpoint.
template [[output]] Conditional A multiline string template that renders a JSON object. This rendered JSON becomes the set of properties for the new output resource. It supports Tera for advanced object creation. Mutually exclusive with jsonnet.
jsonnet [[output]] Conditional A Jsonnet program string that evaluates to a JSON object, which becomes the set of properties for the new resource. This allows for complex logic, functions, and imports. Mutually exclusive with template.

One of template or jsonnet is required.


Templating Engines

Tera Templates

Use the template key for straightforward JSON generation with string interpolation, conditionals, and loops. All header variables, origin_resource, and any related graph nodes are available. For a complete reference on Tera syntax and rescile’s custom filters, see Tera Function & Filter Reference and Templating & Data.

origin_resource = "application"

[[output]]
resource_type = "service_summary"
name = "summary-{{ origin_resource.name }}"
filename = "summary-{{ origin_resource.name }}.json"
mimetype = "application/json"
template = '''
{
  "name":        "{{ origin_resource.name }}",
  "owner":       "{{ origin_resource.owner }}",
  "environment": "{{ origin_resource.environment }}",
  "criticality": "{% if origin_resource.environment == 'prod' %}high{% else %}low{% endif %}"
}
'''

See Using Tera Templates for a full worked example including relationship traversal.

Jsonnet

Use the jsonnet key for complex JSON generation that requires local variables, functions, conditionals, list comprehensions, or reusable imports. Data is injected as external variables and accessed with std.extVar().

External variable How to access
The current resource std.extVar("origin_resource")
Any header variable foo std.extVar("foo")
origin_resource = "server"

[[output]]
resource_type = "k8s_manifest"
name = "svc-{{ origin_resource.name }}"
filename = "svc-{{ origin_resource.name }}.json"
mimetype = "application/json"
jsonnet = """
local origin = std.extVar("origin_resource");
{
  apiVersion: "v1",
  kind: "Service",
  metadata: { name: origin.name },
  spec: {
    ports: [{ port: p } for p in origin.ports]
  }
}
"""

rescile supports sibling imports: .libsonnet files placed in the same directory as the TOML file can be imported directly by filename. See Using Jsonnet for a full example.


How Output Resources Are Created

Understanding the exact mechanics helps you predict what ends up in the graph and what is downloadable via the API.

  1. The engine finds all resources matching origin_resource (and match_on if present).
  2. For each match, the name template is rendered to produce the primary key of the new output resource.
  3. The template or jsonnet program is evaluated. The result must be a valid JSON object.
  4. A new resource of type resource_type is created. The keys of the JSON object become properties of this new resource.
  5. If filename and mimetype are both present, the resource gains a download endpoint automatically reachable via the REST API.
  6. A DESCRIBED_BY relationship is created from the origin resource to the new output resource.
graph LR
    App["application<br><b>billing-api</b>"] -- "DESCRIBED_BY" --> Out["service_summary<br><b>summary-billing-api</b><br>filename: summary-billing-api.json"]

Retrieving Artifacts via the REST API

Once the graph is built, every output resource that has filename and mimetype properties is automatically available for download through the REST API.

List all outputs:

curl "http://localhost:7600/api/outputs/index"

Filter by origin type:

curl "http://localhost:7600/api/outputs/index?origin_type=application"

Download a specific artifact:

curl "http://localhost:7600/api/outputs/service_summary/summary-billing-api/summary-billing-api.json" \
  -o summary-billing-api.json

The index endpoint returns a JSON array with download_url, type, name, filename, mimetype, hash, and an origin object. For the full parameter reference, see REST API Reference.

For usage in CI/CD pipelines, see Retrieving Outputs (REST API) in the End-User Guide.


Common Output Patterns

Terraform Variable Files

Generate .tfvars.json files by traversing related graph nodes and assembling the required structure in a single output rule. The generated resource can then be queried via GraphQL or downloaded directly.

origin_resource = "application"

[[output]]
resource_type = "terraform_variables"
name = "tfvars-{{ origin_resource.name }}"
filename = "tfvars-{{ origin_resource.name }}.json"
mimetype = "application/json"
match_on = [{ property = "environment", value = "prod" }]
template = """
{
  "app_name":    "{{ origin_resource.name }}",
  "owner":       "{{ origin_resource.owner }}",
  "network":     "{{ origin_resource.network[0].name }}",
  "image":       "{{ origin_resource.image[0].name }}"
}
"""

See Terraform Variable Generation for a complete walkthrough.

Kubernetes Manifests

Use Jsonnet’s list comprehensions to generate multi-resource Kubernetes manifests cleanly:

origin_resource = "server"

[[output]]
resource_type = "k8s_service"
name = "svc-{{ origin_resource.name }}"
filename = "svc-{{ origin_resource.name }}.yaml"
mimetype = "text/x-yaml"
jsonnet = """
local origin = std.extVar("origin_resource");
{
  apiVersion: "v1",
  kind: "Service",
  metadata: { name: origin.name, labels: { app: origin.name } },
  spec: {
    selector: { app: origin.name },
    ports: [{ port: p, targetPort: p } for p in origin.ports]
  }
}
"""

Compliance and Audit Reports

The output engine integrates tightly with the compliance graph. After the compliance phase, audit and control resources carry aggregated evidence_summary data that you can render directly into Markdown or OSCAL documents.

# data/output/audit_markdown.toml
origin_resource = "audit"

[[output]]
resource_type = "compliance_report"
name = "report-{{ origin_resource.name }}"
filename = "{{ origin_resource.name }}-report.md"
mimetype = "text/markdown"
template = """
# Compliance Report: {{ origin_resource.audit_name }}

{% for ctrl in origin_resource.control %}
## {{ ctrl.name }} — {{ ctrl.control_name }}
{{ ctrl.description | default(value="") }}

**Evidence:** {{ ctrl.evidence_summary | default(value="{}") | json_encode | safe }}
{% endfor %}
"""

For the full OSCAL and Markdown examples, see Compliance Reports and Generating Audit Artifacts.

Service Catalogs and Summaries

Combine graph traversal with Tera to generate rich service catalog entries that pull data from related nodes:

origin_resource = "application"

[[output]]
resource_type = "catalog_entry"
name = "catalog-{{ origin_resource.name }}"
filename = "catalog-{{ origin_resource.name }}.json"
mimetype = "application/json"
match_on = [{ property = "network_zone", value = "edge" }]
template = '''
{
  "application":  "{{ origin_resource.name }}",
  "owner":        "{{ origin_resource.owner }}",
  "databases":    {{ origin_resource.database | map(attribute="name") | json_encode | safe }},
  "criticality":  "{% if origin_resource.environment == 'prod' %}high{% else %}low{% endif %}"
}
'''

Further Reading

Topic Link
Tera template syntax and rescile custom filters Tera Function & Filter Reference
Templating & Data context (variables, global vs. iteration) Templating & Data
Full [[output]] directive reference Directive Reference
Worked example: Tera service summary Using Tera Templates
Worked example: Jsonnet Kubernetes manifests Using Jsonnet
Worked example: Terraform variable generation Terraform Variable Generation
Compliance and OSCAL reports Compliance Reports / Generating Audit Artifacts
REST API for downloading artifacts REST API Reference
Retrieving outputs in CI/CD Retrieving Outputs (REST API)