As of today, there is no formal support for the app of apps pattern, and the ArgoCD ecosystem lacks a construct where Applications can inherit easily from other Applications.
auto-apps is a stupid simple cli intended to bridge the gap until ApplicationSets are officially supported in ArgoCD. It is designed to fill a gap in the ArgoCD app of apps pattern, where multiple applications are bootstrapped from a single "umbrella" application.
Starting from a given spec.source.path, autoapps will traverse a git repository looking for:
- valid
*.yamlor*.yml - manifests of
type: argoproj.io/v1alpha1andkind: Application - manifests with an annotation present of
autoapps
Using custom argocd tooling, Applications
can utilize the spec.source.plugin spec to template child groups of Applications.
autoapps uses fasttemplate to perform its substitution. Since ArgoCD currently only supports specifying environment variables within plugins, autoapps accepts two forms of substitution:
AUTOAPPS_ prefixed:
Variables prefixed with AUTOAPPS_ are valid candidates for templating, and will have their prefix stripped before templating. For example:
# Parent Application
...
spec:
source:
plugin:
name: autoapps
env:
- name: AUTOAPPS_foo
value: bar
...
# Child Application
...
spec:
source:
path: {{foo}}
...Identifying valid variables for templating via AUTOAPPS_ prefix protects abuse against using protected or private system environment variables as template values. However, one of the restrictions of this means you're limited to valid environment variable names.
Builtin ArgoCD variables:
ArgoCD uses a couple builtin environment variables at runtime that are useful:
# Parent Application
...
spec:
source:
plugin:
name: autoapps
...
# Child Application
...
spec:
source:
targetRevision: {{ARGOCD_APP_SOURCE_TARGET_REVISION}}
...Consider the following app of apps structure:
# Application A syncs Application B and C, which subsequently deploy manifests
+---+
| B | --> App B Manifests
+---+ +---+
| A | -->
+---+ +---+
| C | --> App C Manifests
+---+If you want B and C to dynamically inherit values completely encapsulated within A's manifests:
The "umbrella" application:
# Application A CRD (umbrella app)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: umbrella
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: core
source:
repoURL: https://github.com/joshrwolf/core-bootstrap
targetRevision: HEAD
path: "." # Leverage `autoapps` traversal discovery
plugin:
env:
- name: FOO
value: bar
destination:
server: https://kubernetes.default.svc
namespace: sampleThe subsequent "child" application
# Application B CRD (child app)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mocha
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
project: {{ARGOCD_PROJECT}}
source:
repoURL: {{project_repo}}
targetRevision: {{ARGOCD_APP_SOURCE_TARGET_REVISION}} # leverage standard build environment variables
path: apps/istio
destination:
server: https://kubernetes.default.svc
namespace: istio-systemWhile the above is doable with any of the other templating tools, autoapps keeps the configuration entirely within
the Application CRD, enables runtime configuration, and simplifies "glue" templating with auto discovery of
Applications.
autoapps will skip any applications which are annotated as follows:
# NOTE: Portions of the complete spec are skipped below for brevity
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mocha
annotations:
autoapps-skip-discovery: "true"
...To make this dynamic, you can leverage variable substitution from the parent application as follows:
# Parent Application
...
spec:
source:
plugin:
name: autoapps
env:
- name: AUTOAPPS_skip_mocha
value: "true"
...
# Child Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mocha
annotations:
autoapps-skip-discovery: "{{skip_mocha}}"
...