apply
Apply rendered manifests to the Kubernetes cluster with release tracking.
Synopsis
Section titled “Synopsis”nyl apply [--target <TARGET>] [OPTIONS] <FILE>Description
Section titled “Description”The apply command renders manifests, applies them with server-side apply, and tracks release state.
It applies a Release as its Argo CD Application would deploy it from the
render-tree output, including managed Namespaces, and prunes as an Argo CD sync
prunes. See Rendering Pipeline
for the behavior render, diff, and apply share.
Arguments
Section titled “Arguments”<FILE>- Path to the manifest file to apply (required)
Options
Section titled “Options”Common Options
Section titled “Common Options”--only-source-kind <KIND>- Filter top-level resources by kind (e.g.,ConfigMap,Deployment) or by apiVersion/kind (e.g.,apps/v1/Deployment) before expansion.--only-kind <KIND,...>- Filter final rendered manifests to only include specific kinds (post-render).--exclude-kind <KIND,...>- Filter final rendered manifests to exclude specific kinds (post-render, mutually exclusive with--only-kind).--target <TARGET>- DeploymentTarget whose Cluster supplies values, capabilities, destination identity, and the default kube context. Optional when exactly one target is configured; required when several are available.--release-only- Settle the Release alone instead of taking it from the compiled target; seerender.--allow-secret-inputs- Let the project secrets provider andNYL_*environment variables affect the applied manifests.--max-depth <MAX_DEPTH>- Maximum evaluation depth for recursive resource expansion (default: 10)--track-parent- Track parent resource information in annotations
--input, --inputs, --application-group, --defaults-only, and the cache
options work as for render.
Release Options
Section titled “Release Options”--name <NAME>- Release name (required if no Release in file)--namespace <NAMESPACE>- Release namespace, and the namespace of resources that set none (required if no Release in file)--confirm-prune- Also prune resources whose Argo CD sync option isPrune=confirm, such as managed Namespaces--append-release- Merge current resources with the previous deployed revision and skip pruning removed resources--no-release- Apply resources without creating release revisions, without release metadata, and without pruning--history-limit <N>- Keep at mostNrelease revisions, deleting the oldest after a successful apply;0keeps every revision, otherwiseNmust be at least2. Overrides[release] history_limitinnyl.toml
Cluster Options
Section titled “Cluster Options”--context <CONTEXT>- Kubernetes context to use instead ofCluster.spec.live.context--concurrency <N>- Maximum number of resources applied or pruned at the same time (default: 8;1applies serially)
Apply order and progress
Section titled “Apply order and progress”Nyl applies resources in the same order as Argo CD: Namespaces, cluster policy
(NetworkPolicies, ResourceQuotas, LimitRanges, PodDisruptionBudgets),
ServiceAccounts, Secrets and ConfigMaps, storage, CustomResourceDefinitions, RBAC,
Services, workloads, Ingresses, and APIServices, followed by every other kind,
including custom resources. Built-in kinds are matched by API group and kind, so a
custom kind named like a built-in one, such as a CNI’s NetworkPolicy, is ordered
as a custom resource. Admission webhook configurations are applied last, so a
webhook is not registered before the resources it admits while its backend may
still be starting. As in Argo CD, the resources of one kind form a batch that is
applied concurrently, up to --concurrency at a time, and each batch finishes
before the next starts. Kinds therefore never race a kind they may depend on,
while resources of one kind do not wait for each other.
Before applying the first resource of an API group that a CustomResourceDefinition or APIService registered earlier in the same apply, Nyl refreshes API discovery until the new kinds are served. When several documents describe the same object (the same group, kind, namespace, and name, in any API version; cluster-scoped objects ignore a namespace), only the last one is applied and recorded. A resource that fails to apply does not stop the others; the release is recorded as failed and the command exits non-zero.
Nyl records the new release revision before applying anything. Two applies that record the same revision at the same time therefore fail before the second changes the cluster, but Nyl does not otherwise lock a release: do not run applies of one release in parallel. If an apply fails or is interrupted (Ctrl-C) before it completes, its revision is recorded as failed with only the resources it applied; press Ctrl-C again to exit without waiting for that. A release that renders no resources is still recorded, and its previously deployed resources are pruned.
Pruning deletes the resources a release no longer contains in the reverse of the apply order, so dependents go before what they depend on: admission webhook configurations before the backends they call, custom resources and objects of aggregated APIs before the CustomResourceDefinitions and APIServices behind them, APIServices before their backends, and Namespaces last. As with apply, the resources of one kind are deleted concurrently. Before deleting the next kind, Nyl waits until the deleted resources are gone, so finalizers run while the controllers, CRDs, and webhooks they need still exist. After two minutes of waiting in total, resources still terminating are reported and pruning continues without waiting. A resource whose recorded apiVersion is no longer served is deleted through a version that is; one whose kind is gone entirely (for example, its CRD was deleted) is already gone. A resource that fails to delete, including one behind an aggregated API that is unavailable, stays recorded in the new revision, so the next apply retries deleting it, and the command exits non-zero. Changing a resource’s apiVersion does not prune it.
Like an Argo CD sync, pruning reads each live resource’s
argocd.argoproj.io/sync-options: Prune=false keeps the resource and stops
tracking it, and Prune=confirm keeps it, still tracked, until an apply with
--confirm-prune. Managed Namespaces carry Prune=confirm by default, so
dropping a namespace from a Release never deletes it and its contents
unconfirmed. See Pruning and deletion.
Each resource’s outcome (+ created, ~ updated, = unchanged, ✗ failed) is
printed as soon as it completes, in completion order. The summary is followed by
the time spent in API discovery, validation, apply, and release bookkeeping.
Nyl uses aggregated API discovery (two requests) when the API server supports it
and falls back to per-group discovery otherwise; the timing line names the mode.
Examples
Section titled “Examples”Basic Apply
Section titled “Basic Apply”# Apply a manifest filenyl apply --target production manifest.yaml
# Apply another targetnyl apply --target staging manifest.yaml
# Apply only top-level ConfigMap resourcesnyl apply --target production --only-source-kind ConfigMap manifest.yaml
# Apply only final rendered Deploymentsnyl apply --target production --only-kind Deployment manifest.yamlRelease Management
Section titled “Release Management”# Apply with explicit release name (overrides Release if present)nyl apply --target production --name my-release --namespace default manifest.yaml
# Use different Kubernetes contextnyl apply --target production --context admin@production manifest.yaml
# Keep only the ten most recent release revisionsnyl apply --target production --history-limit 10 manifest.yamlOutput
Section titled “Output”The first apply creates the Release’s resources, including its managed Namespaces. The release namespace shows as updated because Nyl creates it first to store the release state:
$ nyl apply --target production applications/web/release.yaml~ Namespace web+ Namespace web-jobs+ ConfigMap web-jobs/cleanup-schedule+ ConfigMap web/web-config+ Deployment web/web
Summary: 4 created, 1 updated, 0 unchangedTimings: discovery (aggregated) 0.09s, validation 0.00s, apply 0.12s, release 0.01s
Release: web revision 1 deployed successfully to namespace webAfter the Release drops its web-jobs namespace, apply prunes the ConfigMap
there but keeps the managed Namespace, which awaits confirmation:
$ nyl apply --target production applications/web/release.yaml= Namespace web= ConfigMap web/web-config~ Deployment web/web! Kept Namespace web-jobs: its sync option Prune=confirm needs --confirm-prune to delete it
Pruning 1 resources... ✓ Deleted ConfigMap web-jobs/cleanup-schedule
Summary: 0 created, 1 updated, 2 unchangedTimings: discovery (aggregated) 0.08s, validation 0.00s, apply 0.02s, release 0.02s
Release: web revision 2 deployed successfully to namespace web$ nyl apply --target production --confirm-prune applications/web/release.yaml= Namespace web= ConfigMap web/web-config= Deployment web/web
Pruning 1 resources... ✓ Deleted Namespace web-jobs
Summary: 0 created, 0 updated, 3 unchangedTimings: discovery (aggregated) 0.08s, validation 0.00s, apply 0.02s, release 0.02s
Release: web revision 3 deployed successfully to namespace webDry Run
Section titled “Dry Run”Use nyl diff to preview changes before running nyl apply.
No Release Mode
Section titled “No Release Mode”# Apply resources without release tracking or pruningnyl apply --target production --no-release manifest.yaml- Nyl accepts one entry file.
Release.spec.includecan attach additional relative manifest files and glob matches; directory arguments are not supported. - A
Releaseresource in the manifest provides release metadata automatically. - Release state is tracked in Kubernetes Secrets in the release namespace. Use
nyl releaseto inspect history or roll back to a previous revision. - Each release keeps its five most recent revisions unless
[release] history_limitsays otherwise. The oldest revisions beyond the limit are deleted after each successful apply; a failed apply deletes nothing. Deleted revisions can no longer be rolled back to. - The destination namespace and
spec.additionalNamespacesare applied as managed Namespace objects owned by the release, by the group’snamespacepolicy, as in the published tree. Nyl also creates the release namespace before anything else when it is missing, because the release state lives there. --no-releasedisables release tracking entirely. In this mode,nylcannot compute or prune resources removed from subsequent applies.- Resources without
metadata.namespacetake the destination namespace of the Release’s Application, or--namespacefor a file without a Release. The kube context’s default namespace is never used. See Namespaces in diff and apply.
Manifest validation
Section titled “Manifest validation”Use --validate to run project-configured validators. See
Manifest validation for automatic validation, captured
CRD schemas, inherited Cluster contracts, and offline schema vendoring.