diff --git a/Chart.yaml b/Chart.yaml new file mode 100644 index 0000000..78fcd38 --- /dev/null +++ b/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: apps-in-apps +description: > + App-of-Apps Helm chart bootstrapping ArgoCD Applications for this cluster + (e.g. the valheim-gitops game server stack). +type: application +version: 0.1.0 +appVersion: "1.0.0" +home: https://git.smokyzone.de/SmokyZone/apps-in-apps +sources: + - https://git.smokyzone.de/SmokyZone/apps-in-apps +keywords: + - argocd + - app-of-apps + - gitops +maintainers: + - name: SmokyZone diff --git a/README.md b/README.md index e69de29..11b9315 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,63 @@ +# apps-in-apps + +App-of-Apps Helm chart. Renders `argoproj.io/v1alpha1 Application` resources +for every entry configured under `applications` in [`values.yaml`](values.yaml), +including the [`valheim-gitops`](https://git.smokyzone.de/SmokyZone/valheim-gitops) +stack. + +Because this repository *is* a Helm chart, it can be registered in ArgoCD as its +own Application (Helm source), which then manages all child Applications declared +in `values.yaml`. + +## Bootstrapping + +1. Make sure ArgoCD is installed and its API server can reach + `git.smokyzone.de` (add repo credentials if the repos are private). +2. Apply the one-time root Application once: + + ```sh + kubectl apply -f bootstrap/root-application.yaml + ``` + + This registers `apps-in-apps` itself as an ArgoCD Application using this + git repo as a Helm chart source, with automated sync/prune/self-heal. +3. ArgoCD renders `templates/application.yaml`, which creates one child + Application per entry in `applications` (currently: `valheim`, pointing at + the `valheim-gitops` chart). + +## Adding another app + +Add an entry to `applications` in `values.yaml`: + +```yaml +applications: + - name: my-app + enabled: true + source: + repoURL: https://git.smokyzone.de/SmokyZone/my-app.git + targetRevision: main + path: . + destination: + server: https://kubernetes.default.svc + namespace: my-app + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true +``` + +Commit and push — ArgoCD picks it up on the next sync. + +## Structure + +``` +apps-in-apps/ +├── Chart.yaml # Helm chart metadata +├── values.yaml # List of managed Applications +├── templates/ +│ └── application.yaml # Renders one Application per entry +└── bootstrap/ + └── root-application.yaml # One-time manifest to register this chart in ArgoCD +``` diff --git a/bootstrap/root-application.yaml b/bootstrap/root-application.yaml new file mode 100644 index 0000000..25027da --- /dev/null +++ b/bootstrap/root-application.yaml @@ -0,0 +1,27 @@ +# One-time bootstrap manifest. +# +# Apply this manually once (kubectl apply -f bootstrap/root-application.yaml) +# so ArgoCD manages itself as a Helm-based Application. From then on, any +# entry added to values.yaml -> applications[] is rolled out automatically. +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: apps-in-apps + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: https://git.smokyzone.de/SmokyZone/apps-in-apps.git + targetRevision: main + path: . + destination: + server: https://kubernetes.default.svc + namespace: argocd + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/templates/application.yaml b/templates/application.yaml new file mode 100644 index 0000000..2ba8469 --- /dev/null +++ b/templates/application.yaml @@ -0,0 +1,36 @@ +{{- range .Values.applications }} +{{- if .enabled }} +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: {{ .name }} + namespace: {{ $.Values.argocd.namespace }} + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: {{ $.Values.argocd.project }} + source: + repoURL: {{ .source.repoURL }} + targetRevision: {{ .source.targetRevision }} + path: {{ .source.path }} + {{- if or (and .source.helm .source.helm.parameters) (and .source.helm .source.helm.valueFiles) }} + helm: + {{- if .source.helm.parameters }} + parameters: + {{- toYaml .source.helm.parameters | nindent 8 }} + {{- end }} + {{- if .source.helm.valueFiles }} + valueFiles: + {{- toYaml .source.helm.valueFiles | nindent 8 }} + {{- end }} + {{- end }} + destination: + server: {{ .destination.server }} + namespace: {{ .destination.namespace }} + {{- if .syncPolicy }} + syncPolicy: + {{- toYaml .syncPolicy | nindent 4 }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/values.yaml b/values.yaml new file mode 100644 index 0000000..5de5764 --- /dev/null +++ b/values.yaml @@ -0,0 +1,34 @@ +## Default values for the apps-in-apps chart (App-of-Apps pattern). + +argocd: + # Namespace where ArgoCD (and thus the Application CRs) live. + namespace: argocd + # AppProject the generated Applications belong to. + project: default + +# List of child ArgoCD Applications this chart renders. +# Each entry maps 1:1 to an `argoproj.io/v1alpha1 Application`. +applications: + - name: valheim + enabled: true + source: + repoURL: https://git.smokyzone.de/SmokyZone/valheim-gitops.git + targetRevision: main + path: . + helm: + # Extra --set style values merged into the valheim-gitops chart. + # Keep secrets out of here - override via a sealed/external secret + # or ArgoCD parameter overrides instead. + parameters: [] + # valueFiles: + # - values.yaml + destination: + # Empty server means "the cluster ArgoCD itself runs in". + server: https://kubernetes.default.svc + namespace: valheim + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true