apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: k8s-apps-helm-application-set-v1 namespace: argocd annotations: argocd.argoproj.io/debug: "true" spec: goTemplate: true goTemplateOptions: [ "missingkey=error" ] applyNestedSelectors: true generators: # Create a matrix generator that will install all chart in all clusters - matrix: generators: - matrix: generators: # Get all clusters, that are appropriately labeled - clusters: selector: matchExpressions: - key: stage-name operator: Exists - key: cluster-name operator: Exists # In this repo, find all files named argocd.json. # The files are expected to contain {apiVersion: "ysoft.com/v1"} - git: repoURL: https://repo.app.ysoft.com/scm/aws/k8s-apps.git revision: argocd files: - path: "apps/**/argocd.json" values: stageName: '{{ index .metadata.labels "stage-name" }}' clusterName: '{{ index .metadata.labels "cluster-name" }}' provider: '{{ index .metadata.labels "provider" | default "aws" }}' selector: matchLabels: apiVersion: "ysoft.com/v1" - list: # List of one element is a workaround to Argo's inabilility to access '.values.enabled' (which is a result of git generator) in a selector. # The list generator transforms that into '.enabled', which works # As a side effect, it also allows access to previously defined values, like '.values.stageName' elements: # The selector also had troubles with booleans vs. strings, hence the 'yes' and not 'true' - enabled: '{{ dig "stages" .values.stageName "enabled" false . | ternary "yes" "" }}' appName: '{{ .path.basename }}' selector: matchLabels: enabled: "yes" template: metadata: name: "{{ .path.basename }}-{{.values.stageName }}-{{ .values.clusterName }}" spec: project: default destination: server: "{{.server}}" namespace: "{{ .destination.namespace }}" syncPolicy: automated: prune: true syncOptions: - ServerSideApply={{ dig "syncPolicy" "syncOptions" "ServerSideApply" "true" . }} - CreateNamespace={{ dig "syncPolicy" "syncOptions" "CreateNamespace" "true" . }} templatePatch: | spec: sources: # First source is for value files # Default revision is HEAD but can be overriden with clusters.${name}.valuesRevision - repoURL: https://repo.app.ysoft.com/scm/aws/k8s-apps.git targetRevision: '{{ dig "stages" .values.stageName "valuesRevision" (dig "valuesRevision" "" .source) . }}' ref: values # Second source is for chart # Default revision is .source.targetRevision but can be overriden with clusters.${name}.chartRevision - repoURL: "{{ .source.repoURL }}" targetRevision: '{{ dig "stages" .values.stageName "chartRevision" (dig "chartRevision" "" .source) . }}' ref: chart chart: '{{ default "" .source.chart }}' path: '{{ default "" .source.path }}' helm: releaseName: "{{ .path.basename }}" valueFiles: {{- $v := .values }}{{- $ := . }} {{- range $valueFile := ( .valueFiles ) }} - $values/apps/{{$.appName}}/{{ $valueFile | replace "%provider%" $v.provider | replace "%stage%" $v.stageName | replace "%cluster%" $v.clusterName }} {{- end }}