Composition functions

Real logic in compositions.

Advanced14 min · lesson 9 of 12

Early Crossplane compositions were static patch-and-transform, which struggles with real logic — loops, conditionals, computed values. Composition functions fix that: a composition can call one or more functions (containers implementing a gRPC interface) that receive the observed state and the desired composite, run arbitrary logic, and return the set of resources to create. It is the difference between a fixed template and a program that decides what to provision.

PIPELINE COMPOSITION
1Observed + desired composite
input passed into the pipeline
2Step: build
function-patch-and-transform
3Step: replicas-by-size
function-go-templating: loops/conditionals
4Returned resources
the set Crossplane provisions
Each step transforms the desired state; functions run arbitrary logic on every reconcile.
composition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata: { name: postgres-aws }
spec:
mode: Pipeline # function-based composition
compositeTypeRef: { apiVersion: acme.io/v1alpha1, kind: XPostgresInstance }
pipeline:
- step: build
functionRef: { name: function-patch-and-transform }
- step: replicas-by-size
functionRef: { name: function-go-templating } # loops/conditionals in a template

What this unlocks

With functions you can create a variable number of resources (N read replicas from a count), branch on inputs (add a WAF only in prod), pull data from elsewhere, and validate the composite before anything is provisioned. Functions are packaged and versioned like providers, and you compose several into a pipeline where each step transforms the desired state — turning compositions into genuinely programmable platform logic.

Functions run in your control plane — vet them
A composition function is a container that executes during every reconcile with access to the desired and observed state; a malicious or buggy function can create the wrong infrastructure at scale. Pin function versions, use trusted/official functions, review custom ones like production code, and keep their logic deterministic so the same composite always yields the same resources.