Using Jsonnet
While Tera is excellent for simple text substitution, Jsonnet is a data templating language designed for generating configuration data. It supports local variables, functions, conditionals, list comprehensions, and file imports — making it ideal for complex output generation where Tera’s string-based approach becomes hard to maintain.
For advanced Jsonnet techniques consult the official case studies.
Why Jsonnet for Structured Outputs: Jsonnet is the preferred approach whenever generating structured JSON or YAML documents (such as Kubernetes manifests, Terraform
.tf.json, AWS CloudFormation, or complex compliance reports). Because Jsonnet evaluates native data structures rather than strings, it eliminates syntax errors, trailing-comma bugs, quoting issues, and template escaping bugs entirely. Reusable schema fragments and output builders can be cleanly modularized into.libsonnetfiles.
Data Context
When using jsonnet, the data context is injected as External Variables accessed with
std.extVar().
| External variable | Description |
|---|---|
"origin_resource" |
The current resource and all its traversed graph relations |
"<header_key>" |
Any top-level variable defined in the TOML file header |
Example 1: Inline Jsonnet Logic
[[output]]
resource_type = "k8s_manifest"
name = "svc-{{ origin_resource.name }}" # Name generation still uses Tera
jsonnet = """
local origin = std.extVar("origin_resource");
{
apiVersion: "v1",
kind: "Service",
metadata: {
name: origin.name,
labels: {
// Use Jsonnet logic
app: if std.length(origin.application) > 0 then origin.application[0].name else "unknown"
}
}
}
"""
Note: The name, filename, and match_on fields always use Tera even when the
body uses
jsonnet. Only the output body (the JSON object that becomes the resource’s properties) is evaluated as Jsonnet.
Example 2: Modular
data/output/k8s.libsonnet:
{
service(name):: {
apiVersion: "v1",
kind: "Service",
metadata: { name: name }
}
}
data/output/services.toml:
[[output]]
resource_type = "k8s_manifest"
name = "svc-{{ origin_resource.name }}"
jsonnet = """
local k8s = import 'k8s.libsonnet';
local origin = std.extVar("origin_resource");
k8s.service(origin.name)
"""