ApplicationGenerator Reference
The ApplicationGenerator resource enables automatic discovery and generation of ArgoCD Applications from NylRelease files in a Git repository directory.
Note: Repository sources are resolved automatically by Nyl. Depending on context, Nyl may reuse an existing local checkout or clone into its Git cache. See the Git Integration guide for cache management and resolution details.
Resource Definition
Section titled “Resource Definition”apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: string # Generator name (optional) namespace: string # Namespace (optional, typically 'argocd')spec: destination: # Required server: string # Kubernetes API server URL namespace: string # Namespace for generated Applications source: # Required repoURL: string # Git repository URL targetRevision: string # Branch, tag, or commit (default: "HEAD") path: string # Single selector to scan (mutually exclusive with paths) paths: [string] # Multiple selectors to scan (mutually exclusive with path) include: [string] # Include patterns (default: ["*.yaml", "*.yml"]) exclude: [string] # Exclude patterns (default: [".*", "_*", ".nyl/**"]) project: string # ArgoCD project (default: "default") syncPolicy: # Optional sync policy for generated Applications automated: prune: bool selfHeal: bool syncOptions: [string] applicationNameTemplate: string # Naming template (default: "{{ .release.name }}") labels: {string: string} # Labels for generated Applications annotations: {string: string} # Annotations for generated Applications releaseCustomization: # Optional NylRelease override policy allowedPaths: [string] deniedPaths: [string]Field Reference
Section titled “Field Reference”metadata
Section titled “metadata”Standard Kubernetes metadata for the ApplicationGenerator resource itself.
- name (optional): Identifier for this generator
- namespace (optional): Namespace where this resource lives (typically
argocd)
spec.destination
Section titled “spec.destination”Defines where generated Applications should be created and what cluster they target.
-
server (required): Kubernetes API server URL for the target cluster
- Example:
https://kubernetes.default.svc(in-cluster) - Example:
https://my-cluster.example.com:6443(external cluster)
- Example:
-
namespace (required): Namespace where generated Applications are created
- Typically
argocd - Must match where ArgoCD is installed
- Typically
spec.source
Section titled “spec.source”Configures the Git repository and directory scanning behavior.
-
repoURL (required): Git repository URL
- HTTPS:
https://github.com/org/repo.git - SSH:
git@github.com:org/repo.git
- HTTPS:
-
targetRevision (optional, default:
"HEAD"): Git reference to use- Branch:
main,develop - Tag:
v1.0.0 - Commit:
abc123def456
- Branch:
-
path (required if
pathsis not set): Single selector to scan- Relative to repository root
- Can be a file, directory, or glob selector
- Directory selectors are scanned non-recursively by default
-
paths (required if
pathis not set): Multiple selectors to scan- Relative to repository root
- Can include glob selectors (for example
clusters/*/appsor**/*.yaml) - Mutually exclusive with
path
-
include (optional, default:
["*.yaml", "*.yml"]): Glob patterns for files to include- Patterns without
/match basename - Patterns with
/match relative path from repository root - Multiple patterns are OR’d together
- Patterns without
-
exclude (optional, default:
[".*", "_*", ".nyl/**"]): Glob patterns for files to exclude- Takes precedence over include patterns
- Default excludes hidden files (
.), underscore-prefixed files (_), and Nyl cache directories - Example:
["test_*", ".*", "backup*"]
spec.project
Section titled “spec.project”- project (optional, default:
"default"): ArgoCD project name for generated Applications- Must be an existing ArgoCD AppProject
- Used for RBAC and resource restrictions
spec.syncPolicy
Section titled “spec.syncPolicy”Optional default sync policy applied to all generated Applications.
-
automated (optional): Enable automated sync
- prune (bool): Delete resources no longer defined in Git
- selfHeal (bool): Force resource state to match Git
-
syncOptions (optional): List of sync options
CreateNamespace=true: Create destination namespace if missingPruneLast=true: Prune resources after other operationsRespectIgnoreDifferences=true: Respect ignore differencesApplyOutOfSyncOnly=true: Only apply resources that are out of sync
spec.applicationNameTemplate
Section titled “spec.applicationNameTemplate”- applicationNameTemplate (optional, default:
"{{ .release.name }}"): Template for Application names- Currently supports:
{{ .release.name }},{{ .release.namespace }} - Future: Full Handlebars/Tera template support
- Currently supports:
spec.labels
Section titled “spec.labels”Key-value map of labels to add to all generated Applications.
Example:
labels: managed-by: nyl team: platform environment: productionspec.annotations
Section titled “spec.annotations”Key-value map of annotations to add to all generated Applications.
Example:
annotations: docs-url: https://wiki.example.com/apps team-slack: "#platform-team"spec.releaseCustomization
Section titled “spec.releaseCustomization”Controls project-level NylRelease.spec.argocd.applicationOverride customization of generated Applications.
NylReleaseoverrides are always evaluated against effectiveallowedPaths/deniedPaths.+<field>append overrides are matched against the canonical field path without the+prefix.- Example:
spec.syncPolicy.+syncOptionsis checked asspec.syncPolicy.syncOptions.
- Example:
- If
releaseCustomizationis omitted, defaults are used. allowedPathsanddeniedPathsuse dotted field globs:*matches one segment (does not cross dots)**matches multiple segments (crosses dots)
- If both allow and deny match, deny takes precedence.
- If
allowedPathsis omitted or null, defaults are used:metadata.annotations."pref.argocd.argoproj.io/*"spec.info.**spec.ignoreDifferences.**spec.syncPolicy.**
- If
allowedPathsis an empty list, no fields are allowed.
Ignored fields (unsupported/disallowed/invalid) are not applied and are reported in generated Application.spec.info.
File Filtering
Section titled “File Filtering”The ApplicationGenerator scans the configured directory and applies include/exclude patterns:
Pattern Matching
Section titled “Pattern Matching”Patterns use standard glob syntax:
*.yaml- Matches files ending with.yaml*.yml- Matches files ending with.ymlapp*- Matches files starting withapp.*- Matches hidden files (starting with.)_*- Matches files starting with underscoretest_*.yaml- Matchestest_*.yamlfiles**/*.yaml- Recursive match for YAML files- Exact match:
apps.yaml- Matches onlyapps.yaml
Filtering Logic
Section titled “Filtering Logic”- Expand selectors from
path/pathsinto candidate files - File must match at least one
includepattern - File must NOT match any
excludepattern - Nyl parses the file and looks for a NylRelease resource
- If NylRelease found, an Application is generated
Default Patterns
Section titled “Default Patterns”By default:
- Include:
["*.yaml", "*.yml"]- All YAML files - Exclude:
[".*", "_*", ".nyl/**"]- Hidden files, underscore-prefixed files, and Nyl cache paths
This prevents accidental inclusion of:
- Hidden files like
.secrets.yaml,.git/ - Backup files like
_backup.yaml - Test files like
_test_app.yaml
Examples
Section titled “Examples”Basic Usage
Section titled “Basic Usage”Simplest ApplicationGenerator for scanning a directory:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: my-apps namespace: argocdspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: https://github.com/myorg/gitops.git path: appsThis scans apps/ for *.yaml and *.yml files, generates an Application for each NylRelease found.
With Automated Sync
Section titled “With Automated Sync”Enable automatic synchronization and pruning:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: production-apps namespace: argocdspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: https://github.com/myorg/gitops.git targetRevision: production path: clusters/production project: production syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true - PruneLast=trueWith Release-Level +syncOptions
Section titled “With Release-Level +syncOptions”Generator defaults can be extended from a discovered NylRelease instead of replaced.
ApplicationGenerator:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: home-lab namespace: argocdspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: git@gitlab.com:NiklasRosenstein/config.git targetRevision: HEAD path: kasoku.netbird.selfhosted/gitops/home-lab project: home-lab syncPolicy: syncOptions: - ServerSideApply=true - ApplyOutOfSyncOnly=trueNylRelease:
apiVersion: nyl.niklasrosenstein.github.com/v1kind: NylReleasemetadata: name: service-proxies namespace: home-proxyspec: argocd: applicationOverride: spec: syncPolicy: +syncOptions: - RespectIgnoreDifferences=falseGenerated Application excerpt:
spec: syncPolicy: syncOptions: - ServerSideApply=true - ApplyOutOfSyncOnly=true - RespectIgnoreDifferences=falseCustom File Filtering
Section titled “Custom File Filtering”Include only specific files and exclude test files:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: filtered-apps namespace: argocdspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: https://github.com/myorg/gitops.git path: apps include: - "prod-*.yaml" - "core-*.yaml" exclude: - ".*" - "_*" - "test-*" - "*-backup.yaml"With Labels and Annotations
Section titled “With Labels and Annotations”Add metadata to generated Applications:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: team-apps namespace: argocdspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: https://github.com/myorg/gitops.git path: teams/platform/apps labels: team: platform managed-by: nyl environment: production annotations: team-slack: "#platform-team" oncall-pagerduty: "P123ABC"Multi-Cluster Setup
Section titled “Multi-Cluster Setup”Generate Applications for an external cluster:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: staging-cluster-apps namespace: argocdspec: destination: server: https://staging-cluster.example.com:6443 namespace: argocd source: repoURL: https://github.com/myorg/gitops.git targetRevision: main path: clusters/staging project: staging syncPolicy: automated: selfHeal: trueNote: The cluster must be registered in ArgoCD first.
Multiple Generators
Section titled “Multiple Generators”You can have multiple ApplicationGenerators in the same file:
apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: core-appsspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: https://github.com/myorg/gitops.git path: core project: core---apiVersion: argocd.nyl.niklasrosenstein.github.com/v1kind: ApplicationGeneratormetadata: name: addon-appsspec: destination: server: https://kubernetes.default.svc namespace: argocd source: repoURL: https://github.com/myorg/gitops.git path: addons project: addonsGenerated Application Structure
Section titled “Generated Application Structure”For a NylRelease file like this:
apiVersion: nyl.niklasrosenstein.github.com/v1kind: NylReleasemetadata: name: nginx namespace: web---# ... other resources ...The ApplicationGenerator produces:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: nginx # From NylRelease.metadata.name namespace: argocd # From generator.spec.destination.namespace labels: # From generator.spec.labels managed-by: nyl annotations: # From generator.spec.annotations docs-url: https://wiki.example.com/appsspec: project: default # From generator.spec.project source: repoURL: https://github.com/myorg/gitops.git # From generator.spec.source.repoURL path: clusters/default # Directory of the file targetRevision: HEAD # From generator.spec.source.targetRevision plugin: name: nyl-v2 env: - name: NYL_CMP_TEMPLATE_INPUT value: nginx.yaml - name: NYL_RELEASE_NAME value: nginx - name: NYL_RELEASE_NAMESPACE value: web destination: server: https://kubernetes.default.svc # From generator.spec.destination.server namespace: web # From NylRelease.metadata.namespace syncPolicy: # From generator.spec.syncPolicy automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueBehavior
Section titled “Behavior”Processing Flow
Section titled “Processing Flow”-
When
nyl renderencounters an ApplicationGenerator resource:- The ApplicationGenerator is extracted and NOT included in output
- The source path is resolved (from Git by default, or from local override path if configured)
- The resolved source path is scanned for YAML files
- Files are filtered by include/exclude patterns
- Each file is parsed for a NylRelease resource
- An ArgoCD Application is generated for each NylRelease
- Generated Applications are added to the output
-
The ApplicationGenerator acts as an “offline controller” pattern:
- Processing happens during
nyl render - No runtime controller or operator needed
- Deterministic output (same input always produces same output)
- Works in ArgoCD plugin context
- Processing happens during
Path Resolution
Section titled “Path Resolution”By default, source.path / source.paths are resolved using the following precedence:
NYL_APPGEN_REPO_PATH_OVERRIDE, if set- The current local Git checkout, if the current
PWDis inside a Git repository and:- one of the local repository remotes matches
source.repoURLafter normalization source.targetRevisionisHEAD, or exactly matches the current local branch name
- one of the local repository remotes matches
- ArgoCD’s local checkout, when the ArgoCD plugin environment variables match
- Nyl’s normal Git cache/worktree resolution from
source.repoURL+source.targetRevision
If a higher-priority resolution strategy does not match, Nyl falls back to the next one automatically.
Current Local Repository Reuse
Section titled “Current Local Repository Reuse”When you run nyl render, nyl diff, or nyl apply from inside the same Git repository referenced by an ApplicationGenerator, Nyl can reuse the current local checkout instead of creating a separate clone/worktree.
Reuse is enabled only when all of these conditions are satisfied:
- The current
PWDis inside a Git repository - One of that repository’s remotes matches
source.repoURL(normalized URL comparison) source.targetRevisionisHEAD, or exactly matches the current checked-out branch name
Notes:
- A detached
HEADonly matchestargetRevision: HEAD - Branch names must match exactly
- If these checks fail, Nyl falls back to ArgoCD checkout reuse or normal Git resolution
This is useful for local development because ApplicationGenerator sees the files currently checked out in your working tree.
ArgoCD Local Checkout Reuse
Section titled “ArgoCD Local Checkout Reuse”When Nyl runs inside ArgoCD plugin context, it can also reuse ArgoCD’s local checkout instead of cloning:
source.repoURLmust matchARGOCD_APP_SOURCE_REPO_URL(normalized URL comparison)source.targetRevisionmust exactly matchARGOCD_APP_SOURCE_TARGET_REVISIONARGOCD_APP_SOURCE_PATHmust be resolvable to a local source directory
If these checks fail, Nyl falls back to normal Git cache/worktree resolution.
For local testing, set:
export NYL_APPGEN_REPO_PATH_OVERRIDE=/path/to/local/repoOr use:
export NYL_APPGEN_REPO_PATH_OVERRIDE=@gitto resolve the repository root from the current PWD.
When this env var is set, selectors from source.path/source.paths are resolved under that local directory and no local checkout detection, ArgoCD checkout reuse, clone, or worktree checkout is performed for ApplicationGenerator processing.
If the override path is missing/invalid, @git is used outside a Git repository, or the resulting source path does not exist, nyl render fails with a configuration error.
For generated Applications:
- The
pathfield points to the directory containing the NylRelease file - Relative to the repository root
Validation
Section titled “Validation”ApplicationGenerator is validated when parsed:
spec.destination.servermust not be emptyspec.destination.namespacemust not be emptyspec.source.repoURLmust not be empty- Exactly one of
spec.source.pathorspec.source.pathsmust be set spec.source.path/spec.source.pathsselectors must not be empty
Invalid ApplicationGenerator resources cause nyl render to fail with a clear error message.
Limitations (Phase 1)
Section titled “Limitations (Phase 1)”Current limitations:
- No templating:
applicationNameTemplateonly supports basic substitution - Single repository: Cannot scan multiple Git repositories in one generator
These limitations are addressed in Phase 2 (future enhancement).
Next Steps
Section titled “Next Steps”- Bootstrapping Guide - Step-by-step setup
- Best Practices - Production recommendations