Skip to main content
This demo shows how to use Crossplane’s Patch-and-Transform function to translate high-level platform inputs (for example, tier: large) into concrete provider values (for example, db.r5.large). We’ll walk through each of the four transform types supported by the Patch-and-Transform function and add them to a Composition so you can observe their effects. We use a simple WebApp composite resource with the following spec fields:
  • tier (free | standard | premium)
  • environment (string)
  • replicas (integer)
The platform (Composition) decides the actual resource configuration that will be created from those inputs — in this example the Composition constructs a Kubernetes ConfigMap.
When you modify an existing Composition, append new patches/transforms to the existing patches array — do not replace the existing entries. Appending preserves prior behavior while adding new transformations.

1) CompositeResourceDefinition (XRD)

Create an XRD for the WebApp composite resource. Note the spec fields and the status.configName property — the latter is required if you intend to write back values into the XR status using ToCompositeFieldPath.
Apply and verify the XRD:

2) Base Composition (ConfigMap resource)

This base Composition creates a ConfigMap named webapp-config in the function-lab namespace. It uses the Patch-and-Transform function (pt.fn.crossplane.io/v1beta1, function name function-patch-and-transform) with Resources input. Start by mapping spec.environment from the XR into the ConfigMap data.environment.
Apply the Composition:

3) Transform type: map (value mapping)

Use the map transform to translate user-friendly values into concrete provider values. For example, map spec.tier to data.cpuLimit in the ConfigMap. Append this patch to resources[].patches in your Composition:
Apply the updated Composition:
Create an example WebApp XR to test mapping:
Expected ConfigMap (partial):

4) Transform type: CombineFromComposite (combine fields into one)

CombineFromComposite merges multiple XR fields into a single value. For example, concatenate metadata.name and spec.environment into data.appId formatted as <name>-<environment>. Append this patch to resources[].patches:
Apply the Composition, then (optionally) recreate the XR to force a new reconciliation:
Expected ConfigMap (partial):

5) Transform type: ToCompositeFieldPath (write back to XR status)

ToCompositeFieldPath writes a value from the composed resource back into the XR status. This is helpful to expose generated resource names or IDs to platform users. Append this patch to resources[].patches to copy the composed resource’s metadata.name into status.configName of the XR:
The XRD must declare status.configName (or whatever status field you write to). If the XRD does not include the named status property, Crossplane will reject the status write. Reapply the XRD after updating it.
Apply the XRD and Composition, then recreate the XR:
You should see status.configName populated with the composed resource name (for example my-app-97c0b06087b).

6) Transform type: convert (type conversion)

The convert transform converts values between types (for example, integer → string). This is required for ConfigMap data entries which must be strings. Append this patch to resources[].patches:
Apply the updated Composition and recreate the XR to observe the converted value in the ConfigMap:
Expected ConfigMap (partial):

7) Summary & quick reference

The four transforms covered here let you implement flexible, platform-driven mappings and derive provider configuration from high-level inputs. These transforms cover common composition needs: mapping platform-friendly inputs to provider values, aggregating identifiers, surfacing generated names back to users, and converting types for compatibility (e.g., ConfigMap data). Next steps: experiment with these transforms in your own Composition to implement policy-driven defaults, computed values, and richer platform APIs.

Watch Video

Practice Lab