Crossplane compositions
This directory hosts Crossplane Composite Resource Definitions (XRDs) and Compositions that this application provides to the platform — the inverse of the platform chart, which only consumes infrastructure.
Use this stack when your application exposes infrastructure capabilities that other applications can consume. For example, a Keycloak deployment might publish compositions that let other apps provision realms and clients via Claims.
Values reference: compositions/crossplane/
Vikunja itself does not currently expose any Crossplane compositions — it is a leaf application that only consumes infrastructure. This page documents the convention for future contributors who want to publish XRDs (e.g. for delegated project provisioning).
Structure
compositions/crossplane/
├── xrd-<resource>.yaml # CompositeResourceDefinition
├── composition-<resource>.yaml # Composition (maps XRD to managed resources)
└── examples/
└── claim-<resource>.yaml # Example Claim for consumers
Keep one XRD + one Composition per logical resource. Split into separate files rather than bundling — Crossplane applies them independently, and diffs stay readable.
Install
After adding compositions, apply them to the cluster:
kubectl apply -f compositions/crossplane/
Compositions are cluster-scoped — install them once per cluster, not per namespace.
Authoring a new composition
- Define the XRD (
xrd-<resource>.yaml) — the CRD-like schema consumers will write against. Keep the schema minimal; internal knobs belong in the Composition, not the Claim. - Write the Composition (
composition-<resource>.yaml) — maps XRD fields to one or more managed resources (e.g. a KeycloakRealm+ aClientRepresentation). - Add an example Claim (
examples/claim-<resource>.yaml) — a runnable demo consumers can copy. - Test on a cluster — apply the XRD and Composition, then apply the example Claim. Verify the downstream managed resources reconcile before publishing.
Consuming compositions
Other applications consume your XRDs by creating Claims in their platform Helm charts:
apiVersion: <your-group>/v1alpha1
kind: <YourClaimKind>
metadata:
name: consumer-app-claim
spec:
# fields defined by your XRD
Versioning
- Breaking changes to XRD schemas require a new API version (
v1alpha2,v1beta1, etc.) — don't mutatev1alpha1in place - Keep the previous version served alongside the new one until consumers migrate
- Flag breaking changes in the application's CHANGELOG under a
crossplane:prefix