Argo CD any-namespace + dev-apps-source factory wiring #8

Closed
opened 2026-09-22 19:41:16 +00:00 by ginjiruu · 3 comments
Owner

What to build

Two control-plane changes in the IaC repo so per-repo Argo CD applications can be factory-managed:

  1. Configure the portable Argo CD instance to manage Application objects in any namespace (application.namespaces: * in the Argo CD Helm values). The current allowlist (argocd, automation, dev-*) is a tenant-model fossil.
  2. Deploy the orphaned dev-apps-source factory wiring on portable: a Flux GitRepository for lab/dev-apps-source (SSH, read key via ExternalSecret from Vault — verify the Vault secret exists and create a deploy key on the repo if it does not), the dev-apps-source namespace, and a Kustomization syncing the repo's repos path into that namespace.

This makes lab/dev-apps-source the factory repo: per-repo Argo CD Application + AppProject manifests committed there are synced onto portable and picked up by Argo CD.

Acceptance criteria

  • Argo CD's application.namespaces parameter is live-set to * (verified in the params configmap)
  • The dev-apps-source GitRepository is Ready on portable (SSH read key works)
  • A throwaway manifest committed to the repos path of lab/dev-apps-source syncs into the dev-apps-source namespace on portable
  • An Argo CD Application object created in the dev-apps-source namespace is picked up by Argo CD (appears in argocd app list)

Blocked by

  • None — can start immediately
## What to build Two control-plane changes in the IaC repo so per-repo Argo CD applications can be factory-managed: 1. Configure the portable Argo CD instance to manage Application objects in **any namespace** (`application.namespaces: *` in the Argo CD Helm values). The current allowlist (`argocd, automation, dev-*`) is a tenant-model fossil. 2. Deploy the orphaned `dev-apps-source` factory wiring on portable: a Flux GitRepository for `lab/dev-apps-source` (SSH, read key via ExternalSecret from Vault — verify the Vault secret exists and create a deploy key on the repo if it does not), the `dev-apps-source` namespace, and a Kustomization syncing the repo's `repos` path into that namespace. This makes `lab/dev-apps-source` the factory repo: per-repo Argo CD Application + AppProject manifests committed there are synced onto portable and picked up by Argo CD. ## Acceptance criteria - [ ] Argo CD's `application.namespaces` parameter is live-set to `*` (verified in the params configmap) - [ ] The `dev-apps-source` GitRepository is Ready on portable (SSH read key works) - [ ] A throwaway manifest committed to the `repos` path of `lab/dev-apps-source` syncs into the `dev-apps-source` namespace on portable - [ ] An Argo CD Application object created in the `dev-apps-source` namespace is picked up by Argo CD (appears in `argocd app list`) ## Blocked by - None — can start immediately
Author
Owner

Implementation note (verified against argo-cd v3.5.2 source — the version running on portable):

application.namespaces extends only the Application informer. The AppProject informer stays scoped to the control-plane namespace:

  • controller/appcontroller.go:233NewAppProjectInformer(applicationClientset, namespace, ...) (the controller's own namespace)
  • project lookup: GetAppProjectByName(..., ctrl.namespace, ...)projLister.AppProjects(ns).Get(name)

Implication for the factory design (#9): per-repo AppProject objects committed to the factory repo's repos/ path would be synced into the dev-apps-source namespace (the Kustomization's targetNamespace), where Argo CD does not see them. #9 needs either:

  1. per-repo AppProjects placed in the argocd namespace — e.g. a second factory path (e.g. projects/) with a second Kustomization targeting argocd; or
  2. drop per-repo AppProjects and use a shared project (e.g. lab-apps) with per-repo appRBAC rules.

No impact on #8's acceptance criteria (the smoke Application references lab-apps in argocd).

PRs: lab/clusters#1625 (wiring + application.namespaces: *), lab/dev-apps-source#7 (fossil removal + smoke manifests).

Implementation note (verified against argo-cd v3.5.2 source — the version running on portable): `application.namespaces` extends only the **Application** informer. The **AppProject** informer stays scoped to the control-plane namespace: - `controller/appcontroller.go:233` — `NewAppProjectInformer(applicationClientset, namespace, ...)` (the controller's own namespace) - project lookup: `GetAppProjectByName(..., ctrl.namespace, ...)` → `projLister.AppProjects(ns).Get(name)` **Implication for the factory design (#9):** per-repo AppProject objects committed to the factory repo's `repos/` path would be synced into the `dev-apps-source` namespace (the Kustomization's `targetNamespace`), where Argo CD does not see them. #9 needs either: 1. per-repo AppProjects placed in the `argocd` namespace — e.g. a second factory path (e.g. `projects/`) with a second Kustomization targeting `argocd`; or 2. drop per-repo AppProjects and use a shared project (e.g. `lab-apps`) with per-repo `appRBAC` rules. No impact on #8's acceptance criteria (the smoke Application references `lab-apps` in `argocd`). PRs: lab/clusters#1625 (wiring + `application.namespaces: *`), lab/dev-apps-source#7 (fossil removal + smoke manifests).
Author
Owner

Implemented and verified on portable. All four acceptance criteria pass:

  • application.namespaces live-set to *argocd-cmd-params-cm shows application.namespaces: * (propagated values.yaml → argocd-values CM → HelmRelease → helm upgrade).
  • dev-apps-source GitRepository Readystored artifact for revision 'master@sha1:55daf0cc…'; the Vault read key works over SSH from portable. The ExternalSecret produces the identity + known_hosts secret shape (template verified against ESO v2.10.0 semantics: default mergePolicy: Replace drops non-templated keys, so identity is templated explicitly; known_hosts is static).
  • Throwaway manifest syncedConfigMap/das-smoke-test (from repos/_smoke/) is live in the dev-apps-source namespace via the ./repos Kustomization.
  • Application picked up by Argo CDApplication/das-smoke-test in dev-apps-source is reconciled by the controller (OutOfSync/Healthy; manual-only by design, never auto-synced).

PRs (all merged):

  • lab/clusters#1625application.namespaces: * + factory wiring deploy (outer Kustomization in flux-system) + fossil strip (kubetenant OCIRepository, dead kustomizeconfig)
  • lab/clusters#1626 — fix: nest ExternalSecret template under spec.target (CRD dry-run caught it)
  • lab/clusters#1627 — fix: restore dataFrom dropped by #1626 (ESO validating webhook caught it)
  • lab/dev-apps-source#7 — fossil repos/gofantasy-kubetenant.yaml removed + repos/_smoke/ test manifests
  • lab/portable-cluster-argocd-apps#90sourceNamespaces: ["*"] on lab-apps (required: with any-namespace apps, AppProject.IsAppNamespacePermitted rejects apps whose namespace isn't in the project's sourceNamespaces; verified in argo-cd v3.5.2 source)

Open items:

  • repos/_smoke/ is throwaway — delete once you've had a look (the smoke Application will show OutOfSync in the UI until then).
  • See my comment above on the AppProject namespace scoping — it affects #9's per-repo AppProject design (AppProjects are only watched in the control-plane namespace).
Implemented and verified on portable. All four acceptance criteria pass: - [x] **`application.namespaces` live-set to `*`** — `argocd-cmd-params-cm` shows `application.namespaces: *` (propagated values.yaml → argocd-values CM → HelmRelease → helm upgrade). - [x] **`dev-apps-source` GitRepository Ready** — `stored artifact for revision 'master@sha1:55daf0cc…'`; the Vault read key works over SSH from portable. The ExternalSecret produces the `identity` + `known_hosts` secret shape (template verified against ESO v2.10.0 semantics: default `mergePolicy: Replace` drops non-templated keys, so `identity` is templated explicitly; `known_hosts` is static). - [x] **Throwaway manifest synced** — `ConfigMap/das-smoke-test` (from `repos/_smoke/`) is live in the `dev-apps-source` namespace via the `./repos` Kustomization. - [x] **Application picked up by Argo CD** — `Application/das-smoke-test` in `dev-apps-source` is reconciled by the controller (OutOfSync/Healthy; manual-only by design, never auto-synced). **PRs (all merged):** - lab/clusters#1625 — `application.namespaces: *` + factory wiring deploy (outer Kustomization in flux-system) + fossil strip (kubetenant OCIRepository, dead kustomizeconfig) - lab/clusters#1626 — fix: nest ExternalSecret template under `spec.target` (CRD dry-run caught it) - lab/clusters#1627 — fix: restore `dataFrom` dropped by #1626 (ESO validating webhook caught it) - lab/dev-apps-source#7 — fossil `repos/gofantasy-kubetenant.yaml` removed + `repos/_smoke/` test manifests - lab/portable-cluster-argocd-apps#90 — `sourceNamespaces: ["*"]` on `lab-apps` (required: with any-namespace apps, `AppProject.IsAppNamespacePermitted` rejects apps whose namespace isn't in the project's `sourceNamespaces`; verified in argo-cd v3.5.2 source) **Open items:** - `repos/_smoke/` is throwaway — delete once you've had a look (the smoke Application will show OutOfSync in the UI until then). - See my comment above on the AppProject namespace scoping — it affects #9's per-repo AppProject design (AppProjects are only watched in the control-plane namespace).
Author
Owner

Implemented and verified on portable: application.namespaces '*' live in argocd-cmd-params-cm, dev-apps-source GitRepository Ready (Vault SSH read key), repos/ smoke manifest synced into the dev-apps-source namespace, and the smoke Application reconciled by Argo CD. PRs: lab/clusters#1625/#1626/#1627, lab/dev-apps-source#7, lab/portable-cluster-argocd-apps#90. See verification comment above.

Implemented and verified on portable: application.namespaces '*' live in argocd-cmd-params-cm, dev-apps-source GitRepository Ready (Vault SSH read key), repos/ smoke manifest synced into the dev-apps-source namespace, and the smoke Application reconciled by Argo CD. PRs: lab/clusters#1625/#1626/#1627, lab/dev-apps-source#7, lab/portable-cluster-argocd-apps#90. See verification comment above.
Sign in to join this conversation.
No labels
ready-for-agent
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lab/automation#8
No description provided.