Skip to content

feat(presentation): pluggable GitOps backend (ArgoCD + minimal Flux)#104

Draft
sini wants to merge 12 commits into
arnarg:mainfrom
sini:refactor/presentation-backend
Draft

feat(presentation): pluggable GitOps backend (ArgoCD + minimal Flux)#104
sini wants to merge 12 commits into
arnarg:mainfrom
sini:refactor/presentation-backend

Conversation

@sini

@sini sini commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Draft for discussion. Makes the GitOps controller a pluggable presentation backend: ArgoCD is ported behind the seam as the default backend (non-breaking, output byte-identical), and a minimal Flux backend proves pluggability.

Stacked PR. This branch stacks on #102 (build layout seam) and #103 (generators split). The first 7 commits are those two PRs; review only the 5 presentation commits (feat(presentation): add backend selector … onward). It will rebase to a clean diff once #102 lands. It depends on #102 (it edits the restructured build/default.nix); it is independent of #103.

The idea

nixidy's core model — applications → rendered manifests → per-app output dirs — is GitOps-tool-agnostic; only the presentation (synthesizing ArgoCD Applications + the app-of-apps bootstrap) is ArgoCD-specific. Today that's already a model-injection (app-of-apps adds synthetic apps whose resources are Applications, which ride the normal render path). D3 names that the present seam.

A presentation backend is a conditional module that, when selected via nixidy.presentation.backend (default "argocd"), contributes:

  1. per-app options applications.<name>.<backend>.* (threaded into the applications submodule),
  2. controller objects synthesized into backend-owned synthetic apps (reusing the existing render/emit pipeline — no new stage).
modules/presentation/
  default.nix                       # nixidy.presentation.backend selector
  argocd/{default,options,aliases,present}.nix
  flux/{default,options}.nix

modules/nixidy/app-of-apps.nix and modules/applications/argocd.nix are removed (their content moves into the argocd backend).

Back-compat (non-breaking)

The per-app ArgoCD options (project, finalizer, syncPolicy, destination, compareOptions, ignoreDifferences) move to applications.<name>.argocd.*, and the top-level nixidy.appOfApps.* / nixidy.defaults.{finalizer,syncPolicy,destination} move to nixidy.presentation.argocd.*. Every old path value-forwards via mkRenamedOptionModule — existing configurations evaluate unchanged, and with backend = "argocd" the rendered output is byte-identical (the existing test suite is the oracle).

Minimal Flux backend

backend = "flux" synthesizes a shared GitRepository + a per-app Kustomization + a root Kustomization, emitted as raw object attrsets (nixidy already renders plain manifests, so a Flux Kustomization per app-output-dir is the natural mapping). No HelmRelease/full sync-option parity — it's a pluggability proof, not production Flux. Typed Flux modules via fromCRDModule (#103) would be the production path.

Tests

  • All existing ArgoCD tests pass unchanged (default backend + aliases).
  • New: an alias-forwarding test, a bootstrap-manifest test, and a Flux-backend synthesis test.

Why draft

This changes the option schema (behind aliases), so it's the boldest of the three. Opening for discussion on whether pluggable backends fit nixidy's direction before polishing. Completes the "functional core / imperative shell" arc with #102 and #103.

@sini

sini commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

I provided only a minimal impl as a POC for framing discussion.

@arnarg

arnarg commented Jun 12, 2026

Copy link
Copy Markdown
Owner

I've been sitting and thinking about this today and I think I'm for the idea of supporting a pluggable "presentation" backend as long as the original ArgoCD experience doesn't suffer (apart from moving the options a bit, but the aliases help).

I have used Flux a bit at $work but never liked it as much as ArgoCD, how do you propose the environmentPackage layout should be? Won't there need to be a similar app-of-apps setup?

I think the consensus in the Flux community is that the rendered manifest pattern like nixidy uses (commit manifests to git) is an anti-pattern. I think they're more in favour of pushing manifests in OCI artifacts.

I think it would make sense to have the standard flux backend be as close to the argocd one (but make it make sense for flux usage) but also offer a user provided backend if the user wants. Maybe someone could implement a new activation script that builds an OCI artifact and pushes it instead.

Maybe nixidy.presentation.backend could have type with types; either (enum ["argocd" "flux"]) (oneOf [package path (functionTo attrs)]) (I'm not 100% confident this works, but you get the idea).

What do you think?

@sini

sini commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Yeah; that's in line with my thinking. The flux impl in this draft isn't intended to ship; just show what the restructure would look like for ArgoCD. ArgoCD of course remains the first class flagship, we just re-architect the backend model a bit to support (ideally, any) alternative gitops toolchains and more closely match a MVC-style rendering pattern for future enhancements. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants