From 9534db25dcc265388a203dd681566597095f049c Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Wed, 1 Jul 2026 19:57:32 -0700 Subject: [PATCH 1/4] feat: platform ApplicationSet + kargo/kargo-pipelines charts --- argocd/apps/platform/appset.yaml | 51 ++++++++++++++ charts/platform/kargo-pipelines/Chart.yaml | 4 ++ .../kargo-pipelines/templates/stage.yaml | 70 +++++++++++++++++++ .../kargo-pipelines/templates/warehouse.yaml | 14 ++++ charts/platform/kargo-pipelines/values.yaml | 31 ++++++++ charts/platform/kargo/Chart.yaml | 7 ++ charts/platform/kargo/values.yaml | 8 +++ 7 files changed, 185 insertions(+) create mode 100644 argocd/apps/platform/appset.yaml create mode 100644 charts/platform/kargo-pipelines/Chart.yaml create mode 100644 charts/platform/kargo-pipelines/templates/stage.yaml create mode 100644 charts/platform/kargo-pipelines/templates/warehouse.yaml create mode 100644 charts/platform/kargo-pipelines/values.yaml create mode 100644 charts/platform/kargo/Chart.yaml create mode 100644 charts/platform/kargo/values.yaml diff --git a/argocd/apps/platform/appset.yaml b/argocd/apps/platform/appset.yaml new file mode 100644 index 0000000..09fe816 --- /dev/null +++ b/argocd/apps/platform/appset.yaml @@ -0,0 +1,51 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: platform + namespace: argocd +spec: + goTemplate: true + generators: + - matrix: + generators: + - clusters: + selector: + matchLabels: + purpose: platform + - list: + elements: + - app: kargo + namespace: kargo + wave: "0" + - app: kargo-pipelines + namespace: kargo + wave: "1" + template: + metadata: + name: "{{ .app }}-{{ .name }}" + annotations: + argocd.argoproj.io/sync-wave: "{{ .wave }}" + spec: + project: default + sources: + - repoURL: https://github.com/jonathandieu/dieubernetes + targetRevision: HEAD + ref: values + - repoURL: https://github.com/jonathandieu/dieubernetes + targetRevision: HEAD + path: "charts/platform/{{ .app }}" + helm: + valueFiles: + - values.yaml + - "$values/clusters/{{ .name }}/overrides/{{ .app }}.yaml" + ignoreMissingValueFiles: true + destination: + server: "{{ .server }}" + namespace: "{{ .namespace }}" + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/charts/platform/kargo-pipelines/Chart.yaml b/charts/platform/kargo-pipelines/Chart.yaml new file mode 100644 index 0000000..642823f --- /dev/null +++ b/charts/platform/kargo-pipelines/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: kargo-pipelines +description: Kargo Warehouses and Stages for all workload apps +version: 0.1.0 diff --git a/charts/platform/kargo-pipelines/templates/stage.yaml b/charts/platform/kargo-pipelines/templates/stage.yaml new file mode 100644 index 0000000..f427d4a --- /dev/null +++ b/charts/platform/kargo-pipelines/templates/stage.yaml @@ -0,0 +1,70 @@ +{{- range $envName, $env := .Values.environments }} +{{- range $.Values.apps }} +{{- $app := . }} +--- +apiVersion: kargo.akuity.io/v1alpha1 +kind: Stage +metadata: + name: {{ $app.name }}-{{ $envName }} + namespace: kargo +spec: + requestedFreight: + - origin: + kind: Warehouse + name: {{ $app.name }} + sources: + {{- if eq $envName "stage" }} + direct: true + {{- else }} + # prod only receives freight verified by all stage clusters + stages: + {{- range $.Values.environments.stage.clusters }} + - {{ $app.name }}-stage + {{- end }} + {{- end }} + promotionTemplate: + spec: + steps: + - uses: git-clone + config: + repoURL: {{ $.Values.git.repoURL }} + checkout: + - branch: {{ $.Values.git.branch }} + path: ./repo + + # Update image tag in every cluster override file for this environment. + # When a new cluster is added to environments.{{ $envName }}.clusters, + # its override file is automatically included here on next ArgoCD sync. + {{- range $env.clusters }} + - uses: git-update-image + as: update-{{ . }} + config: + path: ./repo + images: + - image: {{ $app.imageRepo }} + fromFreight: true + updates: + - file: clusters/{{ . }}/overrides/{{ $app.name }}.yaml + key: "{{ $app.name }}.image.tag" + {{- end }} + + - uses: git-commit + config: + path: ./repo + message: "chore(kargo): promote {{ $app.name }} to {{ $envName }}" + + - uses: git-push + config: + path: ./repo + + # Trigger ArgoCD sync for every cluster in this environment + {{- range $env.clusters }} + - uses: argocd-update + config: + apps: + - name: {{ $app.name }}-{{ . }} + sources: + - desiredCommitFromStep: git-push + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/platform/kargo-pipelines/templates/warehouse.yaml b/charts/platform/kargo-pipelines/templates/warehouse.yaml new file mode 100644 index 0000000..3f4235c --- /dev/null +++ b/charts/platform/kargo-pipelines/templates/warehouse.yaml @@ -0,0 +1,14 @@ +{{- range .Values.apps }} +--- +apiVersion: kargo.akuity.io/v1alpha1 +kind: Warehouse +metadata: + name: {{ .name }} + namespace: kargo +spec: + subscriptions: + - image: + repoURL: {{ .imageRepo }} + semverConstraint: ">=0.0.0" + discoveryLimit: 5 +{{- end }} diff --git a/charts/platform/kargo-pipelines/values.yaml b/charts/platform/kargo-pipelines/values.yaml new file mode 100644 index 0000000..6509cff --- /dev/null +++ b/charts/platform/kargo-pipelines/values.yaml @@ -0,0 +1,31 @@ +# environments lists which clusters belong to each Kargo Stage. +# `dieuctl cluster create --environment stage` appends to the stage list. +# `dieuctl cluster destroy` removes the cluster from its environment list. +# ArgoCD syncs the updated Kargo Stage definitions automatically. +environments: + stage: + clusters: + - dieubernetes-do-stage-nyc3 + prod: + clusters: + - dieubernetes-do-main-nyc3 + +# apps lists every workload app that goes through the Kargo pipeline. +# Each app gets one Warehouse + one Stage per environment. +apps: + - name: portfolio + imageRepo: ghcr.io/jonathandieu/portfolio + - name: api + imageRepo: ghcr.io/jonathandieu/api + - name: overengineered + imageRepo: ghcr.io/jonathandieu/overengineered + - name: mealie + imageRepo: ghcr.io/mealie-recipes/mealie + - name: plausible + imageRepo: ghcr.io/plausible/analytics + - name: changedetection + imageRepo: ghcr.io/dgtlmoon/changedetection.io + +git: + repoURL: https://github.com/jonathandieu/dieubernetes + branch: main diff --git a/charts/platform/kargo/Chart.yaml b/charts/platform/kargo/Chart.yaml new file mode 100644 index 0000000..17b099f --- /dev/null +++ b/charts/platform/kargo/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: kargo +version: 0.1.0 +dependencies: + - name: kargo + version: "1.10.7" + repository: oci://ghcr.io/akuity/kargo-charts diff --git a/charts/platform/kargo/values.yaml b/charts/platform/kargo/values.yaml new file mode 100644 index 0000000..d6f02ff --- /dev/null +++ b/charts/platform/kargo/values.yaml @@ -0,0 +1,8 @@ +kargo: + api: + adminAccount: + enabled: true + # password hash set via ExternalSecret → kargo-admin-credentials + argocd: + integrationEnabled: true + namespace: argocd From 16a53e27048e716ddbc814e705b8350ab6ae9ecd Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Thu, 2 Jul 2026 07:27:28 -0700 Subject: [PATCH 2/4] fix(kargo): provide admin credentials via ExternalSecret kargo's chart requires api.adminAccount.passwordHash (or api.secret.name) or fails to render. Wires a real 1Password item (Kargo Admin) through ESO instead of stubbing a placeholder. --- .../templates/kargo-admin-credentials.yaml | 21 +++++++++++++++++++ charts/platform/kargo/values.yaml | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 charts/platform/kargo/templates/kargo-admin-credentials.yaml diff --git a/charts/platform/kargo/templates/kargo-admin-credentials.yaml b/charts/platform/kargo/templates/kargo-admin-credentials.yaml new file mode 100644 index 0000000..5f7eb47 --- /dev/null +++ b/charts/platform/kargo/templates/kargo-admin-credentials.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: kargo-admin-credentials + namespace: {{ .Release.Namespace }} + annotations: + argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true +spec: + refreshInterval: 1h + secretStoreRef: + name: onepassword + kind: ClusterSecretStore + target: + name: kargo-admin-credentials + data: + - secretKey: ADMIN_ACCOUNT_PASSWORD_HASH + remoteRef: + key: fhygr5davlgoiugn3oggxovcte/password_hash + - secretKey: ADMIN_ACCOUNT_TOKEN_SIGNING_KEY + remoteRef: + key: fhygr5davlgoiugn3oggxovcte/token_signing_key diff --git a/charts/platform/kargo/values.yaml b/charts/platform/kargo/values.yaml index d6f02ff..42a5ac4 100644 --- a/charts/platform/kargo/values.yaml +++ b/charts/platform/kargo/values.yaml @@ -2,7 +2,8 @@ kargo: api: adminAccount: enabled: true - # password hash set via ExternalSecret → kargo-admin-credentials + secret: + name: kargo-admin-credentials # created by templates/kargo-admin-secret.yaml, sourced from the "Kargo Admin" 1Password item argocd: integrationEnabled: true namespace: argocd From 4c4a3fe1d713fa7dd0bcaa42bed9f25b26f4461e Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Thu, 2 Jul 2026 08:09:28 -0700 Subject: [PATCH 3/4] fix(kargo-pipelines): Warehouse.spec.interval is required by the CRD schema --- charts/platform/kargo-pipelines/templates/warehouse.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/charts/platform/kargo-pipelines/templates/warehouse.yaml b/charts/platform/kargo-pipelines/templates/warehouse.yaml index 3f4235c..b3c57af 100644 --- a/charts/platform/kargo-pipelines/templates/warehouse.yaml +++ b/charts/platform/kargo-pipelines/templates/warehouse.yaml @@ -6,6 +6,7 @@ metadata: name: {{ .name }} namespace: kargo spec: + interval: 5m0s subscriptions: - image: repoURL: {{ .imageRepo }} From 71d24329e2e5d345e8139935c20a17036bd0d750 Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Tue, 7 Jul 2026 06:46:14 -0700 Subject: [PATCH 4/4] fix: correct kargo-pipelines to target real apps/clusters, address Copilot review values.yaml listed 6 apps (portfolio/api/overengineered never had charts) and pre-migration cluster names (dieubernetes-do-stage-nyc3, dieubernetes-do-main-nyc3) that don't match any real cluster. Trimmed to the 3 real workload apps and the actual short cluster names the workloads appset reads overrides from. Also fixes the promotion template's override key, which was writing .image.tag regardless of chart structure - wrong for every app, and doubly wrong for plausible, whose umbrella chart nests the image under the aliased plausible-analytics subchart. Copilot review fixes: hardcoded "kargo" namespace in stage.yaml/warehouse.yaml (now Release.Namespace), duplicate stage reference when ranging over stage clusters for prod's requestedFreight, missing helm.releaseName and SkipDryRunOnMissingResource in the platform appset, and a comment referencing a nonexistent template filename. --- argocd/apps/platform/appset.yaml | 2 ++ .../kargo-pipelines/templates/stage.yaml | 10 +++---- .../kargo-pipelines/templates/warehouse.yaml | 2 +- charts/platform/kargo-pipelines/values.yaml | 27 ++++++++++--------- charts/platform/kargo/values.yaml | 2 +- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/argocd/apps/platform/appset.yaml b/argocd/apps/platform/appset.yaml index 09fe816..7a7e261 100644 --- a/argocd/apps/platform/appset.yaml +++ b/argocd/apps/platform/appset.yaml @@ -35,6 +35,7 @@ spec: targetRevision: HEAD path: "charts/platform/{{ .app }}" helm: + releaseName: "{{ .app }}" valueFiles: - values.yaml - "$values/clusters/{{ .name }}/overrides/{{ .app }}.yaml" @@ -49,3 +50,4 @@ spec: syncOptions: - CreateNamespace=true - ServerSideApply=true + - SkipDryRunOnMissingResource=true diff --git a/charts/platform/kargo-pipelines/templates/stage.yaml b/charts/platform/kargo-pipelines/templates/stage.yaml index f427d4a..9d96c5e 100644 --- a/charts/platform/kargo-pipelines/templates/stage.yaml +++ b/charts/platform/kargo-pipelines/templates/stage.yaml @@ -6,7 +6,7 @@ apiVersion: kargo.akuity.io/v1alpha1 kind: Stage metadata: name: {{ $app.name }}-{{ $envName }} - namespace: kargo + namespace: {{ $.Release.Namespace }} spec: requestedFreight: - origin: @@ -16,11 +16,11 @@ spec: {{- if eq $envName "stage" }} direct: true {{- else }} - # prod only receives freight verified by all stage clusters + # prod only receives freight already verified in stage — one Stage + # per environment, not per cluster, so this is a single reference + # regardless of how many clusters are in the stage environment. stages: - {{- range $.Values.environments.stage.clusters }} - {{ $app.name }}-stage - {{- end }} {{- end }} promotionTemplate: spec: @@ -45,7 +45,7 @@ spec: fromFreight: true updates: - file: clusters/{{ . }}/overrides/{{ $app.name }}.yaml - key: "{{ $app.name }}.image.tag" + key: "{{ $app.imageValueKey }}" {{- end }} - uses: git-commit diff --git a/charts/platform/kargo-pipelines/templates/warehouse.yaml b/charts/platform/kargo-pipelines/templates/warehouse.yaml index b3c57af..3ad6946 100644 --- a/charts/platform/kargo-pipelines/templates/warehouse.yaml +++ b/charts/platform/kargo-pipelines/templates/warehouse.yaml @@ -4,7 +4,7 @@ apiVersion: kargo.akuity.io/v1alpha1 kind: Warehouse metadata: name: {{ .name }} - namespace: kargo + namespace: {{ $.Release.Namespace }} spec: interval: 5m0s subscriptions: diff --git a/charts/platform/kargo-pipelines/values.yaml b/charts/platform/kargo-pipelines/values.yaml index 6509cff..7b973b8 100644 --- a/charts/platform/kargo-pipelines/values.yaml +++ b/charts/platform/kargo-pipelines/values.yaml @@ -1,30 +1,33 @@ -# environments lists which clusters belong to each Kargo Stage. +# environments lists which clusters belong to each Kargo Stage, using the +# short cluster name ArgoCD's cluster secret uses (matches the +# clusters//overrides/ directories the workloads appset reads from — +# not the full dieubernetes-{tier}-{provider}-{region} workspace name). # `dieuctl cluster create --environment stage` appends to the stage list. # `dieuctl cluster destroy` removes the cluster from its environment list. # ArgoCD syncs the updated Kargo Stage definitions automatically. environments: stage: clusters: - - dieubernetes-do-stage-nyc3 + - stage-do-atl1 prod: clusters: - - dieubernetes-do-main-nyc3 + - prod-do-atl1 -# apps lists every workload app that goes through the Kargo pipeline. -# Each app gets one Warehouse + one Stage per environment. +# apps lists every workload app that goes through the Kargo pipeline — each +# must have a real chart under charts/workloads/. imageValueKey is the path +# to the image tag in that chart's own values (relative to the chart root, +# since override files are merged directly as the chart's values) — it +# varies for umbrella charts that wrap an aliased subchart. apps: - - name: portfolio - imageRepo: ghcr.io/jonathandieu/portfolio - - name: api - imageRepo: ghcr.io/jonathandieu/api - - name: overengineered - imageRepo: ghcr.io/jonathandieu/overengineered - name: mealie imageRepo: ghcr.io/mealie-recipes/mealie + imageValueKey: image.tag - name: plausible - imageRepo: ghcr.io/plausible/analytics + imageRepo: ghcr.io/plausible/community-edition + imageValueKey: plausible-analytics.image.tag - name: changedetection imageRepo: ghcr.io/dgtlmoon/changedetection.io + imageValueKey: image.tag git: repoURL: https://github.com/jonathandieu/dieubernetes diff --git a/charts/platform/kargo/values.yaml b/charts/platform/kargo/values.yaml index 42a5ac4..965039c 100644 --- a/charts/platform/kargo/values.yaml +++ b/charts/platform/kargo/values.yaml @@ -3,7 +3,7 @@ kargo: adminAccount: enabled: true secret: - name: kargo-admin-credentials # created by templates/kargo-admin-secret.yaml, sourced from the "Kargo Admin" 1Password item + name: kargo-admin-credentials # created by templates/kargo-admin-credentials.yaml, sourced from the "Kargo Admin" 1Password item argocd: integrationEnabled: true namespace: argocd