Skip to content

Generalize the WebApp abstraction (ascoachingogvaner, wedding-app) #1933

@devantler

Description

@devantler

Summary

Generalize a WebApp archetype — a reusable definition of a containerized web application (workload + route + TLS + scaling + secrets) — so the tenant web apps (ascoachingogvaner, wedding-app) and future ones become a small per-app declaration instead of copied workload boilerplate.

Sibling to the Tenant archetype issue: a Tenant sets up the namespace/isolation/sync; a WebApp defines the application that runs inside it.

Context

ascoachingogvaner (coaching site) and wedding-app are simple web apps. Their workload manifests (Deployment/container or chart, Service, Gateway-API HTTPRoute, optional scaling, optional secrets) live in each tenant's own OCI artifact (synced via the platform-provisioned OCIRepository + Flux Kustomization), not in this repo — but they follow the same web-app shape and will multiply as more tenants onboard. The shape is near-identical: image/chart + host + TLS + a route to the central gateway + (optionally) auth and a secret.

Goal & constraint

One WebApp abstraction → a per-app instance specifying just {image|chart, host, tls, scaling, auth?, secretRefs?}. No more Kustomize overlay/component stacking (the readability reason we're choosing an archetype).

Options to evaluate

  1. Helm app/library chart — recommended start. A webapp chart (named templates for Namespace?/Deployment/Service/HTTPRoute/optional HTTPScaledObject/optional ExternalSecret) consumed via a HelmRelease or referenced from the tenant artifact. values.schema.json gives light typing; stays inside the Flux→HelmRelease model; zero new controllers; no pre-1.0 risk.
  2. KRO WebApp RGD. Typed, kubectl-native, conditional children via includeWhen (KEDA/OIDC). But KRO is pre-1.0 (v1alpha1) and adds an alpha controller at the infrastructure-controllers chokepoint — see the KRO assessment. Better revisited once KRO hits beta/1.0.

Open design question — placement

Tenant workloads live in tenant-owned OCI artifacts. Decide whether the WebApp archetype is:

  • a platform-published chart/RGD that tenants reference from their artifact (platform owns the template, tenant owns the values), or
  • defined per-tenant.

The platform-published option keeps the archetype DRY across tenants and lets us evolve it centrally; it should be the default unless there's a reason to fork per tenant.

Platform constraints any solution must respect

  • HTTPRoute attaches to the central Cilium Gateway in kube-system (reference it, don't recreate it).
  • Optional KEDA HTTP scale-to-zero mirrors the existing 5-point recipe (interceptor repoint + netpol + initial replicas 0).
  • Kyverno mutate policies apply to the rendered pods (security context, anti-affinity, spread, etc.) — the archetype shouldn't fight them.
  • Secrets via ESO + SOPS, never inline.
  • enforce-flux-best-practices (Enforce) requires interval/timeout/retries on any templated HelmRelease.
  • ksail workload validate builds every kustomization standalone (skip-kinds for any new CRD-backed instance).

Acceptance criteria

  • Decision recorded (ADR, or reuse the Tenant-archetype decision) on Helm chart vs KRO, including archetype placement (platform-published vs per-tenant).
  • One app (ascoachingogvaner or wedding-app) migrated as a pilot; behavior-preserving where applicable.
  • A new web app becomes a small declaration.
  • No added Kustomize overlay/component stacking.

Related


🤖 Filed from an architecture discussion with Claude Code. Source: kro.run.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions