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
- 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.
- 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
Related
🤖 Filed from an architecture discussion with Claude Code. Source: kro.run.
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) andwedding-appare simple web apps. Their workload manifests (Deployment/container or chart, Service, Gateway-APIHTTPRoute, optional scaling, optional secrets) live in each tenant's own OCI artifact (synced via the platform-provisionedOCIRepository+ FluxKustomization), 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
webappchart (named templates for Namespace?/Deployment/Service/HTTPRoute/optionalHTTPScaledObject/optional ExternalSecret) consumed via a HelmRelease or referenced from the tenant artifact.values.schema.jsongives light typing; stays inside the Flux→HelmRelease model; zero new controllers; no pre-1.0 risk.WebAppRGD. Typed,kubectl-native, conditional children viaincludeWhen(KEDA/OIDC). But KRO is pre-1.0 (v1alpha1) and adds an alpha controller at theinfrastructure-controllerschokepoint — 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:
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
HTTPRouteattaches to the central CiliumGatewayinkube-system(reference it, don't recreate it).enforce-flux-best-practices(Enforce) requiresinterval/timeout/retries on any templatedHelmRelease.ksail workload validatebuilds every kustomization standalone (skip-kinds for any new CRD-backed instance).Acceptance criteria
ascoachingogvanerorwedding-app) migrated as a pilot; behavior-preserving where applicable.Related
🤖 Filed from an architecture discussion with Claude Code. Source: kro.run.