Skip to content
ReferenceConfiguration

Configuration

Nyl loads project settings from nyl.toml. It searches from the current directory upward, and the nearest nyl.toml wins. At the root of a Git worktree without its own nyl.toml, it also checks nyl/nyl.toml, so a project can keep nyl.toml beside its configuration in nyl/ and still run from anywhere in the worktree. Relative paths in the file resolve against the directory containing it.

Resources name directories and files of this repository with one rule, for example a local ApplicationGroup spec.source.path:

  • A relative path resolves against the directory containing nyl.toml, and may begin with .. segments that deliberately leave it, such as ../applications/web from nyl/nyl.toml.
  • A path that starts with / resolves against the Git worktree root, such as /applications/web.
  • A path must stay inside the worktree and must not traverse a symbolic link.

The two forms name the same directory only for one nyl.toml location, such as nyl/nyl.toml for the examples above. Relative paths move with nyl.toml: use them for Releases kept together with the configuration. Rooted paths do not: use them for fixed places in the repository. Only discovery of control resources is bounded by the nyl.toml directory; sources may name any directory of the worktree.

Paths inside another repository, such as a remote source or a fromGit binding, are relative to that repository’s root instead. Recorded paths, such as rendered provenance and ownership-index inputs, are relative to the nyl.toml directory for files beneath it and start with / for other files of the worktree.

[project]
components_search_paths = ["components"]
helm_chart_search_paths = ["."]
gitops_scaffold_path = "config"
[project.aliases]
"myapi.io/v1/MyKind" = "oci://mycharts.org/my-kind@1.0.0"
  • components_search_paths defaults to ["components"]. Each root is scanned for <root>/<apiVersion>/<kind>/Chart.yaml.
  • helm_chart_search_paths defaults to ["."] and controls Helm chart name resolution.
  • gitops_scaffold_path defaults to "config" and controls where nyl create writes GitOps resources when the project has no root gitops.yaml. Discovery remains project-wide.
  • previous_paths lists earlier locations of the project directory as paths from the Git worktree root, such as ["/"] after moving nyl.toml from the root into nyl/. Commands that render another revision, such as diff-tree --against source and the publish-tree check against HEAD, look there when that revision has no project at the current location.
  • aliases maps an API version and kind to a component shortcut or local component path.

nyl apply and nyl release rollback record every revision of a release as a Kubernetes Secret in the release namespace. Limit how many revisions each release keeps:

[release]
history_limit = 10
  • history_limit defaults to 5. Set it to 0 to keep every revision. Any other value must be at least 2, so the previous revision remains available to roll back to.
  • After a revision deploys successfully, the oldest revisions beyond the limit are deleted. A failed apply deletes nothing, so the last known-good revision and anything still live stay recorded.
  • nyl apply --history-limit <N> overrides the setting for one invocation.

Vendoring is a project-wide policy for remote inputs used by every Cluster and DeploymentTarget in the project:

[vendor]
mode = "preferred"
path = "vendor"
lfs_threshold_bytes = 1048576
  • mode is required when the section exists. disabled ignores the vendor snapshot during rendering, preferred resolves vendor then the disposable source cache then the origin, and required permits only a matching vendored artifact.
  • path defaults to vendor and must remain beneath the directory containing nyl.toml. Nyl excludes this subtree from GitOps YAML discovery.
  • lfs_threshold_bytes defaults to 1 MiB. Helm and Git archives always use Git LFS rules; RemoteManifest blobs and the files fromGit Release input bindings lock use LFS at or above this threshold.

nyl init --vendor <MODE> writes this section with the selected mode when it creates nyl.toml.

The committed lock identifies artifacts by a deterministic fingerprint of the complete request coordinate. Multiple Releases requesting the same coordinate share one lock entry and one blob. See nyl vendor for snapshot maintenance.

Deployment values, Kubernetes capabilities, and kube contexts live in Kubernetes-shaped Cluster and DeploymentTarget resources, not in nyl.toml.

Remote Git operations run the git command line, so Nyl authenticates as your git does: SSH config and agent, and credential helpers. Runners without those, such as CI jobs holding a deploy key or an access token in a secret, can name dedicated credentials for state pushes and publish-tree:

[[git.credentials]]
url = "https://gitlab.example.com/platform/" # prefix of the repository URLs it applies to
token_env = "NYL_STATE_TOKEN" # HTTPS token from this environment variable
username = "oauth2" # default x-access-token; GitLab expects oauth2
[[git.credentials]]
url = "git@github.com:acme/"
ssh_key_file = "/run/secrets/deploy-key" # or ssh_key_env with the key itself

Each entry sets exactly one of ssh_key_file, ssh_key_env, and token_env; the longest matching url prefix wins. nyl.toml names only where a secret is. A token reaches git through a credential helper that reads it from the child process’s environment, never through the command line, and a key from ssh_key_env is written to a temporary file readable only by you. A variable an entry names but the environment lacks fails the command before it contacts the repository.

A target-aware render resolves one DeploymentTarget and its referenced Cluster. Values merge recursively in this order:

Cluster.spec.values < DeploymentTarget.spec.values

Target values win at every conflicting leaf. Templates receive the merged map as values, the sanitized Cluster as cluster, and the target as target. Cluster.spec.live is local connection configuration and is never exposed to templates or generated output.

A targetless render receives no cluster or target. Pass Kubernetes capabilities explicitly when a Helm chart depends on them:

Terminal window
nyl render \
--kube-version 1.31.0 \
--kube-api-versions v1,apps/v1 \
applications/example.yaml

Given /home/user/platform/nyl.toml:

[project]
components_search_paths = ["components", "/opt/shared-components"]
helm_chart_search_paths = [".", "charts"]

Nyl resolves the paths to /home/user/platform/components, /opt/shared-components, /home/user/platform, and /home/user/platform/charts.

Terminal window
nyl validate
nyl validate --strict
nyl schema config

The published project schema is available at reference/schemas/nyl.schema.json.

[approval] lookup = ["./ci/approvers.sh"] optionally names a command and arguments that return CI approvers as JSON. It runs before unit effects, with a 30-second timeout. See Approvals for its context variables, response format, identity precedence, and GitHub lookup.

Set a default exact version per native infrastructure kind:

[units.OpenTofu]
version = "1.13.2"
[units.Terraform]
version = "1.9.8"

A unit’s spec.version overrides its kind’s project default. The selected version enters its execution key, and a different installed binary fails before native effects. Without a version, the installed tool runs and its version is recorded in the receipt without triggering execution when the binary changes. Nyl never downloads tools.