Getting started with Crossplane composition functions: build portable, reusable cloud APIs

Crossplane is a way to treat your cloud services like Kubernetes objects: you declare a high-level API, and Crossplane stitches together provider-managed resources to satisfy it. If you’ve used Terraform modules or Helm charts, think of Crossplane’s Compositions as a way to package an opinionated, reusable infrastructure API your platform team can give developers — but driven by Kubernetes’ control loop. (docs.crossplane.io)

This article walks through a recent, practical pattern that’s great for getting started: using Composition Functions (a newer Crossplane capability) to implement reusable, environment-aware Compositions (for example, “managed PostgreSQL for dev/staging/prod”) without turning your YAML into unreadable templates. I’ll explain the concepts, show a minimal Composition-as-pipeline, and give pragmatic tips so your first experiment isn’t a headache.

Why Composition Functions?

Think of it like making music: a Composition is the song structure (verse, chorus, bridge), while a Composition Function is a synth patch or effect you plug in to shape a sound. You could try to tune every parameter by hand, but sometimes a small script or plugin gives you the expressive control you need.

How Composition Functions fit into a Composition

A simple getting-started recipe (conceptual)

  1. Install Crossplane and the cloud provider providers you need (AWS, GCP, Azure, or the Crossplane provider for managed Postgres). The official Crossplane docs have step-by-step installation instructions for the control plane and provider configuration. (docs.crossplane.io)
  2. Define an XRD that represents your platform API — e.g., CompositePostgresInstance with fields for size, storage, environment, and credentials target. This XRD is the contract developers will request. (docs.crossplane.io)
  3. Create a Composition in Pipeline mode that references a function pipeline. The pipeline runs one or more functions that can:
    • decide which cloud provider resource to create based on the “environment” field (dev → cheaper, prod → managed DB),
    • generate small derived names and labels,
    • attach connection secret wiring and RBAC rules. The Composition’s pipeline lets you orchestrate that logic in code rather than complex YAML patches. (docs.crossplane.io)
  4. Implement or reuse a Composition Function. Start with the community function “patch-and-transform” or a simple Go function example from the Crossplane docs, then iterate. The docs note you can develop and test a function without a running Crossplane cluster — helpful for rapid feedback. (docs.crossplane.io)
  5. Create a composite resource (an instance of your XRD). Crossplane will run the Composition pipeline and materialize the managed cloud resources and secrets that implement your custom API. Inspect the composite resource’s status and generated resource refs to debug.

Minimal Composition YAML (illustrative)

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: composite-postgres-composition
spec:
  compositeTypeRef:
    apiVersion: database.example.org/v1
    kind: CompositePostgresInstance
  mode: Pipeline
  pipeline:
    - step: choose-and-render
      functionRef:
        name: function-patch-and-transform
      input:
        apiVersion: pt.fn.crossplane.io/v1beta1
        kind: Resources
        resources:
          - name: postgres
            base:
              apiVersion: database.aws.crossplane.io/v1beta1
              kind: RDSInstance
              spec:
                forProvider:
                  instanceClass: db.t3.medium

This snippet shows a Composition in Pipeline mode that calls a function named function-patch-and-transform. The function receives the composite resource and a base “resource template” and returns the rendered managed resources. In practice you’d add conditionals or a separate step to choose different provider resources for different environments. (docs.crossplane.io)

Where to find examples and community patterns

Practical tips and pitfalls

A balanced note Crossplane’s model is powerful but different from traditional IaC. If you’re used to imperative tooling or single-team ownership of infra, the mental model of platform-defined APIs and a control plane will require some organizational shifts (ownership, RBAC, and testing). But once you land the model, Composition Functions let platform teams keep policy and complexity in a maintainable place while developers consume a simple Kubernetes-style API.

Closing chord If you want a practical first experiment: define a tiny CompositePostgresInstance XRD, author a Pipeline Composition that uses the patch-and-transform function to produce an RDS or CloudSQL resource depending on an environment field, and create a composite resource for “dev”. Watch Crossplane create the managed resource and the connection secret — it’s a satisfying “plug in the amp and hear the note” moment.

Sources for further reading

Happy composing — think of Compositions as your band’s arrangement and functions as the pedals that make the sound yours.