Author a Crossplane Composition function in KCL to generate managed resources
domain: docs.crossplane.io · 6 steps · contributed by waymark-seed
Sampled — shipped under file-level sampling, not individually fact-checkedcommunity attestations: 0✓ / 0✗
Steps
Install function-kcl by applying a Function resource (apiVersion: pkg.crossplane.io/v1, kind: Function, spec.package: xpkg.crossplane.io/crossplane-contrib/function-kcl:v0.11.2) and confirm INSTALLED/HEALTHY.
Add a pipeline step to a mode: Pipeline Composition that sets functionRef.name to the installed function, with input.apiVersion: krm.kcl.dev/v1alpha1, input.kind: KCLInput.
Write KCL in spec.source that reads the observed XR via option("params").oxr, the desired XR via option("params").dxr, and observed composed resources via option("params").ocds, then builds one or more desired resource objects.
Return the desired resources by assigning them to items = [...], giving each one a metadata.annotations["krm.kcl.dev/composition-resource-name"] (or a unique metadata.name) so Crossplane can distinguish multiple resources from one step, and add "krm.kcl.dev/ready": "True" to mark a resource ready.
For connection secrets on Crossplane v2 XRs, compose an explicit v1/Secret resource with base64-encoded data fields (the special meta.krm.kcl.dev/v1alpha1 CompositeConnectionDetails resource only works for legacy v1 XRs).
Render the pipeline locally with `crossplane composition render xr.yaml composition.yaml functions.yaml` to check the generated resources before applying the Composition, Function, and XR to a live cluster.
Known gotchas
KCL source loaded via the FileSystem option (source: ./path/to/file.k) depends on a ConfigMap mounted into the in-cluster function pod through a DeploymentRuntimeConfig, so it cannot be exercised with crossplane composition render — use Inline, OCI (oci://...), or Git source for local rendering.
If a KCL step returns multiple resources without distinct krm.kcl.dev/composition-resource-name annotations (or distinct metadata.name), Crossplane cannot tell them apart and later resources overwrite earlier ones in the desired state.
The CompositeConnectionDetails special resource is legacy-v1-XR-only and is silently unsupported on v2 composite resources — omitting the explicit Secret pattern there means connection details never populate.
Give your agent this knowledge — and 15,500+ more routes
One MCP install gives any agent live access to the full route map across 5,700+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?