Skip to content
Kubernetes GitOpsRendered Layout

Rendered Layout

Nyl renders one DeploymentTarget at a time into its configured publication prefix. This page describes the tree it writes there; the workflow pages describe the commands that produce, compare, and publish it.

For each release, Nyl writes:

<target-prefix>/<group-output>/<release>/<kind>[.<group>]/[<namespace>/]<name>.yaml
<target-prefix>/<group-output>/<release>/crd/<crd-name>.yaml
<target-prefix>/_nyl/catalog/appproject.argoproj.io/<namespace>/<project>.yaml
<target-prefix>/_nyl/catalog/application.argoproj.io/<namespace>/<application>.yaml
<target-prefix>/_nyl/catalog/application.argoproj.io/<argocd-namespace>/<target>-catalog.yaml
<target-prefix>/_nyl/index.json

The catalog uses the same per-resource layout as a release, beneath the fixed _nyl/catalog directory that the catalog Application, a project-written parent, or an ApplicationSet syncs.

Every resource is written to its own file, and Helm # Source: comments are retained. CRDs live in crd/<crd-name>.yaml whatever their API version. Other resources are placed by identity: the lowercased kind and API group form a directory that matches kubectl’s resource syntax, followed by the namespace directory when metadata.namespace is set, and the object name. For example:

configmap/api/settings.yaml
deployment.apps/api/web.yaml
clusterrole.rbac.authorization.k8s.io/system%3Aaggregate-to-admin.yaml

The API version is not part of the path, so changing an object’s apiVersion updates its file in place. Characters that are unsafe in a path segment, such as :, are percent-encoded, which keeps distinct objects in distinct files. Windows device names such as con or aux have their first character encoded (%63on.yaml). A segment that would exceed the 255-byte file name limit keeps its first characters followed by _ and a digest of the full name; all other names are written unchanged. Nyl rejects two resources whose paths differ only in case, because they would collide on case-insensitive filesystems. When a file or directory is renamed only by case, for example an object name or a Release, the next render writes it under its new name. Directories left empty by removed files are deleted. Generated Argo CD Applications use source.directory.recurse: true, so every nested directory is included.

Every workload manifest has # Nyl-Provenance: comments identifying its repository-relative source document and Nyl expansion chain. Synthesized resources identify the operation that generated them. These comments are serialization metadata and do not add annotations to the Kubernetes object.

The parent catalog Application points at <target-prefix>/_nyl/catalog and is generated by default. Apply it once after the first publication; automated sync then keeps its child Applications, projects, and its own manifest current.

Managed Namespaces normally live in the owning workload’s release directory. When several workload Applications use one namespace, their ApplicationGroups must agree on a sharedNamespaces owner. Release keeps ownership in the selected workload, External emits no Namespace, and Dedicated writes the Namespace to <target-prefix>/_nyl/namespaces/<identity>/namespace/<name>.yaml with a separate generated Application. Nyl rejects overlapping resource ownership.

The versioned _nyl/index.json index records target identity, source provenance, owned files, and SHA-256 hashes. Nyl preserves unowned files and rejects changes to indexed files that were made outside Nyl.