The next gitops task for my home cluster was to make ArgoCD automatically install new applications when I add them to the configuration git repository.

In this post, I’m going to show how to set up an Argo CD git generator ApplicationSet and point it at a specific directory in a configuration repository.

Software Versions

Here are the versions of the software I used while writing this post.

Software Version
argocd 3.2.6
kubernetes 1.34.1
talos 1.12.4

Pre-requisites

To follow along with this post, you will need:

Background

ArgoCD is great for managing things deployed into your cluster, but I don’t want to have to explicitly add a new app every time I add something to my cluster. Insetad, I want to be able to just merge a PR and have Argo detect the new App and install it, or update existing Apps.

To do this we’re going to create an Argo Git Generator ApplicationSet that watches a directory in our configuration repository.

Creating the Git Generator

Make a directory in your configuration repository - I used argocd/apps. For each new app, you’re going to create a subdirectory to contain your manifest files and a config.yaml that tells Argo what namespace to use and what cluster to deploy it to.

Here’s the ApplicationSet:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: apps-git-generator
  namespace: argocd
spec:
  goTemplate: true
  generators:
    - git:
        repoURL: 'https://github.com/USERNAME/CONFIGURATION_REPOSITORY.git'
        revision: HEAD
        requeueAfterSeconds: 60
        files:
          - path: "argocd/apps/**/config.yaml"
          - path: "argocd/disabled/**/config.yaml"
            exclude: true
  template:
    metadata:
      # Accessing the 'app' block from config.yaml via dot notation
      name: '{{ .app.name }}'
      labels:
        target-cluster: '{{ .app.clusterName }}'
    spec:
      # Logic: use app.project, fallback to "default" string
      project: '{{ if .app.project }}{{ .app.project }}{{ else }}default{{ end }}'
      source:
        repoURL: 'https://github.com/USERNAME/CONFIGURATION_REPOSITORY.git'
        targetRevision: HEAD
        path: '{{ .path.path }}'
      destination:
        # Fallback logic for cluster URL
        server: '{{ if .app.clusterUrl }}{{ .app.clusterUrl }}{{ else }}https://kubernetes.default.svc{{ end }}'
        namespace: '{{ if .app.namespace }}{{ .app.namespace }}{{ else }}default{{ end }}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true
          - PrunePropagationPolicy=foreground
          - PruneLast=true

Add the ApplicationSet to your git configuration repository and then apply it to your cluster.

# Assumeing you're at the root of your configuration repository
git add argocd/infrastructure/argocd/git-generator-ApplicationSet.yaml && \
    git commit argocd/infrastructure/argocd/git-generator-ApplicationSet.yaml -m 'Add git generator Argo ApplicationSet' && \
    git push && \
    kubectl apply -f argocd/infrastructure/argocd/git-generator-ApplicationSet.yaml

A couple of notes - this will only load manifests from directories that have a valid config.yaml file. The manifests will be installed into the namespace specified in config.yaml. This makes it easy to uninstall an app - git mv appdir/config.yaml appdir/disabled.config.yaml && git commit -m 'Disable appdir' appdir && git push

Here’s the format the ApplicationSet expects in config.yaml files:

app:
  name: "name-of-app"  # This will appear in as the app's name in Argo CD.
  namespace: "namespace-you-want" # This will be created if necessary
  # Use a label-friendly name
  clusterName: sisyphus
  # Use the full URL for the destination
  clusterUrl: https://kubernetes.default.svc # I'm having argo manage the cluster it's installed in

Your configuration repository layout should look similar to this

repo-root -- argocd
               \____ apps
                      \___ appdir
                            |___ config.yaml
                            |
                            |___ something.yaml
                            |
                            |___ something-else.yaml

Now that the ApplicationSet is installed, whenever you merge changes to your default branch, ArgoCD will detect them and apply them.

This ApplicationSet is configured to wait two minutes between between checks of your git repository. You can force an immediate check either with the Refresh Apps button on the ArgoCD applications page or by running argocd app get APPNAME --refresh.

Note - if you have multiple apps in the same git repository, refreshing any of them will cause Argo to deploy any changes to all of the other apps in that repository too.

No more manual app creation, just merge and apps automatically start up.

Summary

You have:

  • Installed an Argo CD git generator ApplicationSet in your cluster so that you can add/update/remove applications from your cluster by making changes to your configuration repository with git.