ArgoCD ApplicationSet
KSailβs ArgoCD bootstrap creates a single Application CR that syncs manifests from a local OCI registry. ApplicationSet extends this by generating multiple Applications from a single template β useful for multi-environment deployments, multi-tenant clusters, and directory-based project structures.
Prerequisites
Section titled βPrerequisitesβInitialize a KSail project with ArgoCD as the GitOps engine:
ksail cluster init --gitops-engine ArgoCDksail cluster createThis scaffolds a ksail.yaml with spec.cluster.gitOpsEngine: ArgoCD and creates the cluster with:
- ArgoCD installed via Helm
- A bootstrap
ApplicationCR namedksailpointing to the local OCI registry - Automated sync, pruning, and self-healing enabled
How It Works
Section titled βHow It WorksβDuring ksail cluster create, KSail creates a single Application that syncs everything in the k8s/ source directory:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: ksail namespace: argocdspec: project: default source: repoURL: oci://<registry>/<project> targetRevision: dev path: "." destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueYou can add ApplicationSet manifests to your source directory to generate additional Applications alongside the bootstrap one.
Directory Generator
Section titled βDirectory GeneratorβThe directory generator creates one Application per subdirectory in a given path. This is useful for managing multiple independent workloads from a monorepo layout.
Project Layout
Section titled βProject Layoutβmy-app/βββ ksail.yaml # gitOpsEngine: ArgoCDβββ k8s/β βββ kustomization.yamlβ βββ applicationset.yaml # ApplicationSet manifestβ βββ apps/β βββ frontend/β β βββ deployment.yamlβ β βββ service.yamlβ βββ backend/β β βββ deployment.yamlβ β βββ service.yamlβ βββ monitoring/β βββ deployment.yamlβ βββ service.yamlApplicationSet Manifest
Section titled βApplicationSet ManifestβCreate k8s/applicationset.yaml:
apiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata: name: apps namespace: argocdspec: goTemplate: true goTemplateOptions: ["missingkey=error"] generators: - git: repoURL: oci://<registry>/<project> revision: dev directories: - path: apps/* template: metadata: name: "{{.path.basename}}" spec: project: default source: repoURL: oci://<registry>/<project> targetRevision: dev path: "{{.path.path}}" destination: server: https://kubernetes.default.svc namespace: "{{.path.basename}}" syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueThis generates three Applications (frontend, backend, monitoring), each deployed to its own namespace.
Add the ApplicationSet to your kustomization and push:
ksail workload pushksail workload reconcileGit Generator
Section titled βGit GeneratorβThe git generator can also use config.json files in each directory to pass parameters to the template. This enables per-application configuration without duplicating manifests.
Project Layout
Section titled βProject Layoutβmy-app/βββ ksail.yamlβββ k8s/β βββ kustomization.yamlβ βββ applicationset.yamlβ βββ envs/β βββ dev/β β βββ config.jsonβ βββ staging/β β βββ config.jsonβ βββ production/β βββ config.jsonEach config.json contains environment-specific parameters:
{ "env": "dev", "namespace": "app-dev", "replicas": 1}ApplicationSet Manifest
Section titled βApplicationSet ManifestβapiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata: name: multi-env namespace: argocdspec: goTemplate: true goTemplateOptions: ["missingkey=error"] generators: - git: repoURL: oci://<registry>/<project> revision: dev files: - path: envs/*/config.json template: metadata: name: "app-{{.env}}" spec: project: default source: repoURL: oci://<registry>/<project> targetRevision: dev path: "envs/{{.env}}" destination: server: https://kubernetes.default.svc namespace: "{{.namespace}}" syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueCombining with Tenant Management
Section titled βCombining with Tenant ManagementβKSailβs tenant management generates ArgoCD AppProject and Application resources per tenant. You can replace per-tenant Applications with a single ApplicationSet that auto-discovers tenant directories:
apiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata: name: tenants namespace: argocdspec: goTemplate: true goTemplateOptions: ["missingkey=error"] generators: - git: repoURL: oci://<registry>/<project> revision: dev directories: - path: tenants/* template: metadata: name: "tenant-{{.path.basename}}" spec: project: "{{.path.basename}}" source: repoURL: oci://<registry>/<project> targetRevision: dev path: "{{.path.path}}" destination: server: https://kubernetes.default.svc namespace: "{{.path.basename}}" syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true-
Inspect the bootstrap Application to get the correct
repoURLandtargetRevisionvalues for your ApplicationSet templates:Terminal window ksail workload get application ksail -n argocd -o yaml -
Use
ksail workload pushandksail workload reconcileto deploy ApplicationSet manifests β they flow through the same OCI push pipeline as regular manifests. -
Combine with multi-environment workflows by using separate
ksail.<env>.yamlconfigs and ApplicationSet generators. See Multi-Environment Workflows for the--configpattern.