Crossplane logo
Crossplane logo
  • Why Control Planes?
  • Documentation
  • Community
  • Blog
  • Crossplane GitHub
  • Crossplane Slack
Crossplane Documentation - v2.0
Welcome
What's Crossplane?
What's New in v2?
Get Started
Install Crossplane
Get Started With Composition
Get Started With Managed Resources
Get Started With Operations
Composition
Composite Resources
Composite Resource Definitions
Compositions
Composition Revisions
Environment Configs
Managed Resources
Managed Resources
Managed Resource Definitions
Managed Resource Activation Policies
Usages
Operations
Operations
Cron Operations
Watch Operations
Packages
Providers
Functions
Configurations
Image Configs
Guides
Crossplane Pods
Metrics
Function Patch and Transform
Releasing Crossplane Extensions
Write a Composition Function in Go
Write a Composition Function in Python
Disabling Unused Managed Resources
Implementing safe-start in Providers
Troubleshoot Crossplane
Upgrade Crossplane
Upgrade to Crossplane v2
Uninstall Crossplane
CLI Reference
Command Reference
API Reference
Learn More
Release Cycle
Feature Lifecycle
Contributing Guide
Crossplane Roadmap
v2.0
Latest
master v2.0-preview v2.0
Latest
v1.20 v1.19

Function Patch and Transform

On this page
  • Install the function
  • Resource templates
  • Create a patch
    • Selecting fields
      • Example field paths
  • Reuse a patch
  • Patching between resources
  • Patch with EnvironmentConfigs
    • Patch a composite resource
    • Patch an individual resource
  • Types of patches
    • FromCompositeFieldPath
    • ToCompositeFieldPath
    • CombineFromComposite
    • CombineToComposite
    • FromEnvironmentFieldPath
    • ToEnvironmentFieldPath
    • CombineFromEnvironment
    • CombineToEnvironment
  • Transform a patch
    • Convert transforms
      • Converting strings to booleans
      • Converting numbers to booleans
      • Converting booleans to numbers
      • Converting strings to float64
      • Converting strings to objects
      • Converting strings to arrays
    • Map transforms
    • Match transform
      • Match an exact string
      • Match a regular expression
      • Using default values
    • Math transforms
      • clampMin
      • clampMax
      • Multiply
    • String transforms
      • String convert
      • String format
      • Join
      • Regular expression type
      • Trim prefix
      • Trim suffix
  • Patch policies
    • fromFieldPath policy
    • toFieldPath policy
  • Composite resource connection details
  • Resource readiness checks
    • Match a string
    • Match an integer
    • Match that a field exists
    • Always consider a resource ready
    • Match a condition
    • Match a boolean
Report a problem
View page source

Function Patch and Transform allows you to write a Composition that specifies managed resource (MR) templates, and uses “patch and transform” operations to fill them out. Crossplane fills the templates out with values copied from a composite resource (XR).

A patch copies a value from one resource and patches it onto another resource. A transform modifies the values before applying the patch.

Tip

All Compositions used Patch and Transform before Crossplane added support for composition functions.

Function Patch and Transform works like legacy mode: Resources Compositions, which Crossplane deprecated in v1.17. The difference is that it uses a mode: Pipeline Composition and a function instead of a mode: Resources Composition.

Here’s an example Composition that uses Function Patch and Transform. When you create an AcmeBucket XR that uses this Composition, Crossplane uses the template to create the Amazon S3 Bucket MR.

Crossplane copies the value from the AcmeBucket XR’s spec.desiredRegion field and patch it onto the Bucket managed resource’s spec.forProvider.region field.

 1apiVersion: apiextensions.crossplane.io/v1  2kind: Composition  3metadata:  4  name: example  5spec:  6  compositeTypeRef:  7    apiVersion: custom-api.example.org/v1alpha1  8    kind: AcmeBucket  9  mode: Pipeline 10  pipeline: 11  - step: patch-and-transform 12    functionRef: 13      name: function-patch-and-transform 14    input: 15      apiVersion: pt.fn.crossplane.io/v1beta1 16      kind: Resources 17      resources: 18      - name: storage-bucket 19        base: 20          apiVersion: s3.aws.m.upbound.io/v1beta1 21          kind: Bucket 22          spec: 23            forProvider: 24              region: "us-east-2" 25        patches: 26        - type: FromCompositeFieldPath 27          fromFieldPath: spec.desiredRegion 28          toFieldPath: spec.forProvider.region 
Note
Patch and transform is best for simpler compositions. It intentionally doesn’t support features like loops and conditionals.

Install the function

You must install Function Patch and Transform before you can use it in a Composition. Apply this manifest to install Function Patch and Transform:

1apiVersion: pkg.crossplane.io/v1 2kind: Function 3metadata: 4  name: function-patch-and-transform 5spec: 6  package: xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.8.2 
Tip
Read the Composition page to learn more about Compositions and composition functions.

Resource templates

The resources field the function’s input defines the set of things that a composite resource creates when it uses this function.

For example, the input can define a template to create a virtual machine and an associated storage bucket at the same time.

Tip
Crossplane calls the resources a composite resource creates composed resources.

The resources field lists the individual resources with a name. This name identifies the resource inside the Composition. It isn’t related to the external name used with the Provider.

The contents of the base are identical to creating a standalone managed resource.

This example uses provider-upjet-aws to define a S3 storage Bucket and EC2 compute Instance.

After defining the apiVersion and kind, define the spec.forProvider fields defining the settings of the resource.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: storage-bucket  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: "us-east-2" 11- name: vm 12  base: 13    apiVersion: ec2.aws.m.upbound.io/v1beta1 14    kind: Instance 15    spec: 16      forProvider: 17        ami: ami-0d9858aa3c6322f73 18        instanceType: t2.micro 19        region: "us-east-2" 

When a composite resource uses this function, the composite resource creates two new managed resources with all the provided spec.forProvider settings.

The spec supports any settings used in a managed resource, including applying annotations and labels or using a specific providerConfigRef.

Note
Use the crossplane.io/external-name annotation on the resource to set the resource’s name in the external system (like AWS).
Tip
You can use Function Patch and Transform to template any kind of Kubernetes resource.

Create a patch

Each entry in the resources list can include a list of patches. The patches field takes a list of patches to apply to the individual resource.

Each patch has a type, which defines what kind of patch action Crossplane applies.

Patches reference fields inside different resources depending on the patch type, but all patches reference a fromFieldPath and toFieldPath.

The fromFieldPath is the path to the patch’s input values. The toFieldPath is the path the patch applies to.

Here’s an example of a patch that copies a value from the composite resource’s spec.field1 field to the composed Bucket’s labels.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: storage-bucket  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: "us-east-2" 11  patches: 12    - type: FromCompositeFieldPath 13      fromFieldPath: spec.field1 14      toFieldPath: metadata.labels["patchLabel"] 

Selecting fields

Crossplane selects fields in a composite resource or managed resource with a subset of JSONPath selectors, called “field paths.”

Field paths can select any field in a composite resource or managed resource object, including the metadata, spec or status fields.

Field paths can be a string matching a field name or an array index, in brackets. Field names may use a . character to select child elements.

Example field paths

Here are some example selectors from a composite resource object.

SelectorSelected element
kindkind
spec.desiredRegioneu-north-1
spec.resourceRefs[0].namemy-example-978mh-r6z64
 1$ kubectl get composite -o yaml  2apiVersion: example.org/v1alpha1  3kind: Example  4metadata:  5  # Removed for brevity  6  labels:  7    crossplane.io/composite: my-example-978mh  8spec:  9  desiredRegion: eu-north-1 10  field1: field1-text 11  crossplane: 12    resourceRefs: 13    - apiVersion: s3.aws.m.upbound.io/v1beta1 14      kind: Bucket 15      name: my-example-978mh-r6z64 16    - apiVersion: s3.aws.m.upbound.io/v1beta1 17      kind: Bucket 18      name: my-example-978mh-cnlhj 19    - apiVersion: s3.aws.m.upbound.io/v1beta1 20      kind: Bucket 21      name: my-example-978mh-rv5nm 

Reuse a patch

You can reuse a patch object on multiple resources by using a PatchSet.

To create a PatchSet, define a patchSets object in the function’s input.

Each patch inside a PatchSet has a name and a list of patches.

Apply the PatchSet to a resource with a patch type: PatchSet. Set the patchSetName to the name of the PatchSet.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3patchSets:  4- name: my-patchset  5  patches:  6  - type: FromCompositeFieldPath  7    fromFieldPath: spec.desiredRegion  8    toFieldPath: spec.forProvider.region  9resources: 10- name: bucket1 11  base: 12    # Removed for brevity 13  patches: 14    - type: PatchSet 15      patchSetName: my-patchset 16- name: bucket2 17  base: 18    # Removed for brevity 19  patches: 20    - type: PatchSet 21      patchSetName: my-patchset 
Important

A PatchSet can’t contain other PatchSets.

Crossplane ignores any transforms or policies in a PatchSet.

Patching between resources

Function Patch and Transform can’t directly patch between two composed resources. For example, generating a network resource and patching the resource name to a compute resource.

A resource can patch to a user-defined status field in the composite resource. Another resource can then read from that Status field to patch a field.

First, define a custom status in the composite resource Definition and a custom field, for example secondResource

 1kind: CompositeResourceDefinition  2# Removed for brevity.  3spec:  4  # Removed for brevity.  5  versions:  6  - name: v1alpha1  7    schema:  8      openAPIV3Schema:  9        type: object 10        properties: 11          spec: 12            # Removed for brevity. 13          status: 14              type: object 15              properties: 16                secondResource: 17                  type: string 

Inside the function input the resource with the source data uses a ToCompositeFieldPath patch to write data to the status.secondResource field in the composite resource.

The destination resource uses a FromCompositeFieldPath patch to read data from the composite resource status.secondResource field in the composite resource and write it to a label named secondResource in the managed resource.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    # Removed for brevity  9  patches: 10    - type: ToCompositeFieldPath 11      fromFieldPath: metadata.name 12      toFieldPath: status.secondResource 13- name: bucket2 14  base: 15    apiVersion: s3.aws.m.upbound.io/v1beta1 16    kind: Bucket 17    # Removed for brevity 18  patches: 19    - type: FromCompositeFieldPath 20      fromFieldPath: status.secondResource 21      toFieldPath: metadata.labels['secondResource'] 

Describe the composite resource to view the resources and the status.secondResource value.

 1$ kubectl describe composite  2Name:         my-example-jp7rx  3Spec:  4  # Removed for brevity  5  Resource Refs:  6    Name:         my-example-jp7rx-gfg4m  7    # Removed for brevity  8    Name:         my-example-jp7rx-fttpj  9Status: 10  # Removed for brevity 11  Second Resource:         my-example-jp7rx-gfg4m 

Describe the destination managed resource to see the label secondResource.

1$ kubectl describe bucket 2kubectl describe bucket my-example-jp7rx-fttpj 3Name:         my-example-jp7rx-fttpj 4Labels:       crossplane.io/composite=my-example-jp7rx 5              secondResource=my-example-jp7rx-gfg4m 

Patch with EnvironmentConfigs

Crossplane uses EnvironmentConfigs to create in-memory data stores. Compositions can read and write from this data store as part of the patch process.

EnvironmentConfigs can predefine data that Compositions can use or a composite resource can write data to their in-memory environment for other resources to read.

Note

Read the EnvironmentConfigs page for more information on using EnvironmentConfigs.

To apply a patch using EnvironmentConfigs, first define which EnvironmentConfigs to use with environment.environmentConfigs.

Use either a reference or a selector to identify the EnvironmentConfigs to use.

1apiVersion: apiextensions.crossplane.io/v1 2kind: Composition 3# Removed for Brevity 4spec: 5  environment: 6    environmentConfigs: 7      - ref: 8          name: example-environment 9  # Removed for Brevity 

Patch a composite resource

To patch between the composite resource and the in-memory environment use patches inside of the environment.

Use the ToCompositeFieldPath to copy data from the in-memory environment to the composite resource.

Use the FromCompositeFieldPath to copy data from the composite resource to the in-memory environment.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3environment:  4  patches:  5  - type: ToCompositeFieldPath  6    fromFieldPath: tags  7    toFieldPath: status.envTag  8  - type: FromCompositeFieldPath  9    fromFieldPath: metadata.name 10    toFieldPath: newEnvironmentKey 

Individual resources can use any data written to their in-memory environment.

Patch an individual resource

To patch an individual resource, inside the patches of the resource, use ToEnvironmentFieldPath to copy data from the resource to the in-memory environment.

Use FromEnvironmentFieldPath to copy data to the resource from the in-memory environment.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: vpc  5  base:  6    apiVersion: ec2.aws.m.upbound.io/v1beta1  7    kind: VPC  8    spec:  9      forProvider: 10        cidrBlock: 172.16.0.0/16 11  patches: 12  - type: ToEnvironmentFieldPath 13    fromFieldPath: status.atProvider.id 14    toFieldPath: vpcId 15  - type: FromEnvironmentFieldPath 16    fromFieldPath: tags 17    toFieldPath: spec.forProvider.tags 

The EnvironmentConfigs page has more information on EnvironmentConfigs options and usage.

Types of patches

Function Patch and Transform supports multiple patch types, each using a different source for data and applying the patch to a different location.

Summary of Crossplane patches

Patch TypeData SourceData Destination
FromCompositeFieldPathA field in the composite resource.A field in the composed resource.
ToCompositeFieldPathA field in the composed resource.A field in the composite resource.
CombineFromCompositeMultiple fields in the composite resource.A field in the composed resource.
CombineToCompositeMultiple fields in the composed resource.A field in the composite resource.
FromEnvironmentFieldPathData in the in-memory environmentA field in the composed resource.
ToEnvironmentFieldPathA field in the composed resource.The in-memory environment.
CombineFromEnvironmentMultiple fields in the in-memory environment.A field in the composed resource.
CombineToEnvironmentMultiple fields in the composed resource.A field in the in-memory environment.
Note

All the following examples use the same set of Compositions, CompositeResourceDefinitions and EnvironmentConfigs. Only the applied patches change between examples.

All examples rely on provider-aws-s3 to create resources.

 1apiVersion: apiextensions.crossplane.io/v1  2kind: Composition  3metadata:  4  name: example-composition  5spec:  6  compositeTypeRef:  7    apiVersion: example.org/v1alpha1  8    kind: Example  9  environment: 10    environmentConfigs: 11    - ref: 12        name: example-environment 13  mode: Pipeline 14  pipeline: 15  - step: patch-and-transform 16    functionRef: 17      name: function-patch-and-transform 18    input: 19      apiVersion: pt.fn.crossplane.io/v1beta1 20      kind: Resources 21      resources: 22      - name: bucket1 23        base: 24          apiVersion: s3.aws.m.upbound.io/v1beta1 25          kind: Bucket 26          spec: 27            forProvider: 28              region: us-east-2 29      - name: bucket2 30        base: 31          apiVersion: s3.aws.m.upbound.io/v1beta1 32          kind: Bucket 33          spec: 34            forProvider: 35              region: us-east-2 

 1apiVersion: apiextensions.crossplane.io/v1  2kind: CompositeResourceDefinition  3metadata:  4  name: examples.example.org  5spec:  6  group: example.org  7  names:  8    kind: Example  9    plural: examples 10  versions: 11  - name: v1alpha1 12    served: true 13    referenceable: true 14    schema: 15      openAPIV3Schema: 16        type: object 17        properties: 18          spec: 19            type: object 20            properties: 21              field1: 22                type: string 23              field2: 24                type: string 25              field3: 26                type: string 27              desiredRegion: 28                type: string 29              boolField: 30                type: boolean 31              numberField: 32                type: integer 33          status: 34              type: object 35              properties: 36                url: 37                  type: string 

 1apiVersion: example.org/v1alpha1  2kind: Example  3metadata:  4  namespace: default  5  name: my-example  6spec:  7  field1: "field1-text"  8  field2: "field2-text"  9  desiredRegion: "eu-north-1" 10  boolField: false 11  numberField: 10 

 1apiVersion: apiextensions.crossplane.io/v1beta1  2kind: EnvironmentConfig  3metadata:  4  name: example-environment  5data:  6  locations:  7    us: us-east-2  8    eu: eu-north-1  9  key1: value1 10  key2: value2 

FromCompositeFieldPath

The FromCompositeFieldPath patch takes a value in a composite resource and applies it to a field in the composed resource.

Tip
Use the FromCompositeFieldPath patch to apply options from users in their XRs to settings in managed resource forProvider settings.

For example, to use the value desiredRegion provided by a user in a composite resource to a managed resource’s region.

The fromFieldPath value is a field in the composite resource.

The toFieldPath value is the field in the composed resource to change.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: FromCompositeFieldPath 13      fromFieldPath: spec.desiredRegion 14      toFieldPath: spec.forProvider.region 

View the managed resource to see the updated region

1$ kubectl describe bucket 2Name:         my-example-qlr68-29nqf 3# Removed for brevity 4Spec: 5  For Provider: 6    Region:  eu-north-1 

ToCompositeFieldPath

The ToCompositeFieldPath writes data from an individual composed resource to the composite resource that created it.

Tip
Use ToCompositeFieldPath patches to take data from one composed resource in a Composition and use it in a second composed resource in the same Composition.

For example, after Crossplane creates a new managed resource, take the value hostedZoneID and store it in the composite resource’s status.

Important
To patch to composite resource status fields, you must first define the custom status fields in the CompositeResourceDefinition.
 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: ToCompositeFieldPath 13      fromFieldPath: status.atProvider.hostedZoneId 14      toFieldPath: status.hostedZoneId 

View the created managed resource to see the Hosted Zone Id field.

1$ kubectl describe bucket 2Name:         my-example-p5pxf-5vnp8 3# Removed for brevity 4Status: 5  At Provider: 6    Hosted Zone Id:       Z2O1EMRO9K5GLX 7    # Removed for brevity 

Next view the composite resource and confirm the patch applied to the status

1$ kubectl describe composite 2Name:         my-example-p5pxf 3# Removed for brevity 4Status: 5  Hosted Zone Id: Z2O1EMRO9K5GLX 

CombineFromComposite

The CombineFromComposite patch takes values from the composite resource, combines them and applies them to the composed resource.

Tip
Use the CombineFromComposite patch to create complex strings, like security policies and apply them to a composed resource.

For example, use the XR value desiredRegion and field2 to generate the managed resource’s name

The CombineFromComposite patch only supports the combine option.

The variables are the list of fromFieldPath values from the composite resource to combine.

The only supported strategy is strategy: string.

Optionally you can apply a string.fmt, based on Go string formatting to specify how to combine the strings.

The toFieldPath is the field in the composed resource to apply the new string to.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: CombineFromComposite 13      combine: 14        variables: 15          - fromFieldPath: spec.desiredRegion 16          - fromFieldPath: spec.field2 17        strategy: string 18        string: 19          fmt: "my-resource-%s-%s" 20      toFieldPath: metadata.name 

Describe the managed resource to see the applied patch.

1$ kubectl describe bucket 2Name:         my-resource-eu-north-1-field2-text 

CombineToComposite

The CombineToComposite patch takes values from the composed resource, combines them and applies them to the composite resource.

Tip
Use CombineToComposite patches to create a single field like a URL from multiple fields in a managed resource.

For example, use the managed resource name and region to generate a custom url field.

Important
Writing custom fields in the status field of a composite resource requires defining the custom fields in the CompositeResourceDefinition first.

The CombineToComposite patch only supports the combine option.

The variables are the list of fromFieldPath the managed resource to combine.

The only supported strategy is strategy: string.

Optionally you can apply a string.fmt, based on Go string formatting to specify how to combine the strings.

The toFieldPath is the field in the composite resource to apply the new string to.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: CombineToComposite 13      combine: 14        variables: 15          - fromFieldPath: metadata.name 16          - fromFieldPath: spec.forProvider.region 17        strategy: string 18        string: 19          fmt: "https://%s.%s.com" 20      toFieldPath: status.url 

View the composite resource to verify the applied patch.

1$ kubectl describe composite 2Name:         my-example-bjdjw 3API Version:  example.org/v1alpha1 4Kind:         Example 5# Removed for brevity 6Status: 7  # Removed for brevity 8  URL:                     https://my-example-bjdjw-r6ncd.us-east-2.com 

FromEnvironmentFieldPath

The FromEnvironmentFieldPath patch takes values from the in-memory environment and applies them to the composed resource.

Tip
Use FromEnvironmentFieldPath to apply custom managed resource settings based on the current environment.

For example, use the environment’s locations.eu value and apply it as the region.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11    patches: 12    - type: FromEnvironmentFieldPath 13      fromFieldPath: locations.eu 14      toFieldPath: spec.forProvider.region 

Verify managed resource to confirm the applied patch.

1kubectl describe bucket 2Name:         my-example-8vrvc-xx5sr 3# Removed for brevity 4Spec: 5  For Provider: 6    Region:  eu-north-1 7  # Removed for brevity 

ToEnvironmentFieldPath

Important
For more information about using an EnvironmentConfig, read the EnvironmentConfigs documentation.

The ToEnvironmentFieldPath patch takes a value from the composed resource and applies it to the in-memory environment.

Tip
Use ToEnvironmentFieldPath to write data to the environment that any FromEnvironmentFieldPath patch can access.

For example, use the desired region value and apply it as the environment’s key1.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11    patches: 12    - type: ToEnvironmentFieldPath 13      fromFieldPath: spec.forProvider.region 14      toFieldPath: key1 

Because the environment is in-memory, there is no command to confirm the patch wrote the value to the environment.

CombineFromEnvironment

Important
For more information about using an EnvironmentConfig, read the EnvironmentConfigs documentation.

The CombineFromEnvironment patch combines multiple values from the in-memory environment and applies them to the composed resource.

Tip
Use CombineFromEnvironment patch to create complex strings, like security policies and apply them to a managed resource.

For example, combine multiple fields in the environment to create a unique annotation .

The CombineFromEnvironment patch only supports the combine option.

The only supported strategy is strategy: string.

The variables are the list of fromFieldPath values from the in-memory environment to combine.

Optionally you can apply a string.fmt, based on Go string formatting to specify how to combine the strings.

The toFieldPath is the field in the composed resource to apply the new string to.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: CombineFromEnvironment 13      combine: 14        strategy: string 15        variables: 16        - fromFieldPath: key1 17        - fromFieldPath: key2 18        string: 19          fmt: "%s-%s" 20      toFieldPath: metadata.annotations[EnvironmentPatch] 

Describe the managed resource to see new annotation.

1$ kubectl describe bucket 2Name:         my-example-zmxdg-grl6p 3# Removed for brevity 4Annotations:  EnvironmentPatch: value1-value2 5# Removed for brevity 

CombineToEnvironment

Important
For more information about using an EnvironmentConfig, read the EnvironmentConfigs documentation.

The CombineToEnvironment patch combines multiple values from the composed resource and applies them to the in-memory EnvironmentConfig environment.

Tip
Use CombineToEnvironment patch to create complex strings, like security policies to use in other managed resources.

For example, combine multiple fields in the managed resource to create a unique string and store it in the environment’s key2 value.

The string combines the managed resource Kind and region.

The CombineToEnvironment patch only supports the combine option.

The only supported strategy is strategy: string.

The variables are the list of fromFieldPath values in the managed resource to combine.

Optionally you can apply a string.fmt, based on Go string formatting to specify how to combine the strings.

The toFieldPath is the key in the environment to write the new string to.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: CombineToEnvironment 13      combine: 14        strategy: string 15        variables: 16        - fromFieldPath: kind 17        - fromFieldPath: spec.forProvider.region 18        string: 19          fmt: "%s.%s" 20      toFieldPath: key2 

Because the environment is in-memory, there is no command to confirm the patch wrote the value to the environment.

Transform a patch

When applying a patch, Crossplane supports modifying the data before applying it as a patch. Crossplane calls this a “transform” operation.

Summary of Crossplane transforms.

Transform TypeAction
convertConverts an input data type to a different type. Also called “casting.”
mapSelects a specific output based on a specific input.
matchSelects a specific output based on a string or regular expression.
mathApplies a mathematical operation on the input.
stringChange the input string using Go string formatting.

Apply a transform directly to an individual patch with the transforms field.

A transform requires a type, indicating the transform action to take.

The other transform field is the same as the type, in this example, map.

The other fields depend on the patch type used.

This example uses a type: map transform, taking the input spec.desiredRegion, matching it to either us or eu and returning the corresponding AWS region for the spec.forProvider.region value.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: bucket1  5  base:  6    apiVersion: s3.aws.m.upbound.io/v1beta1  7    kind: Bucket  8    spec:  9      forProvider: 10        region: us-east-2 11  patches: 12    - type: FromCompositeFieldPath 13      fromFieldPath: spec.desiredRegion 14      toFieldPath: spec.forProvider.region 15      transforms: 16        - type: map 17          map: 18            us: us-east-2 19            eu: eu-north-1 

Convert transforms

The convert transform type changes the input data type to a different data type.

Tip
Some provider APIs require a field to be a string. Use a convert type to change any boolean or integer fields to strings.

A convert transform requires a toType, defining the output data type.

1patches: 2- type: FromCompositeFieldPath 3  fromFieldPath: spec.numberField 4  toFieldPath: metadata.label["numberToString"] 5  transforms: 6    - type: convert 7      convert: 8        toType: string 

Supported toType values:

toType valueDescription
boolA boolean value of true or false.
float64A 64-bit float value.
intA 32-bit integer value.
int64A 64-bit integer value.
stringA string value.
objectAn object.
arrayAn array.

Converting strings to booleans

When converting from a string to a bool Crossplane considers the string values 1, t, T, TRUE, True and true equal to the boolean value True.

The strings 0, f, F, FALSE, False and false are equal to the boolean value False.

Converting numbers to booleans

Crossplane considers the integer 1 and float 1.0 equal to the boolean value True. Any other integer or float value is False.

Converting booleans to numbers

Crossplane converts the boolean value True to the integer 1 or float64 1.0.

The value False converts to the integer 0 or float64 0.0

Converting strings to float64

When converting from a string to a float64 Crossplane supports an optional format: quantity field.

Using format: quantity translates size suffixes like M for megabyte or Mi for megabit into the correct float64 value.

Note
Refer to the Go language docs for a full list of supported suffixes.

Add format: quantity to the convert object to enable quantity suffix support.

1- type: convert 2  convert: 3   toType: float64 4   format: quantity 

Converting strings to objects

Crossplane converts JSON strings to objects.

Add format: json to the convert object which is the only supported string format for this conversion.

1- type: convert 2  convert: 3   toType: object 4   format: json 
Tip
This conversion is useful for patching keys in an object.

The following example adds a tag to a resource with a customized key:

 1    - type: FromCompositeFieldPath  2      fromFieldPath: spec.clusterName  3      toFieldPath: spec.forProvider.tags  4      transforms:  5      - type: string  6        string:  7          type: Format  8          fmt: '{"kubernetes.io/cluster/%s": "true"}'  9      - type: convert 10        convert: 11          toType: object 12          format: json 

Converting strings to arrays

Crossplane converts JSON strings to arrays.

Add format: json to the convert object which is the only supported string format for this conversion.

1- type: convert 2  convert: 3   toType: array 4   format: json 

Map transforms

The map transform type maps an input value to an output value.

Tip
The map transform is useful for translating generic region names like US or EU to provider specific region names.

The map transform compares the value from the fromFieldPath to the options listed in the map.

If Crossplane finds the value, Crossplane puts the mapped value in the toFieldPath.

Note
Crossplane throws an error for the patch if the value isn’t found.

spec.field1 is the string "field1-text" then Crossplane uses the string firstField for the annotation.

If spec.field1 is the string "field2-text" then Crossplane uses the string secondField for the annotation.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.field1 4    toFieldPath: metadata.annotations["myAnnotation"] 5    transforms: 6      - type: map 7        map: 8          "field1-text": "firstField" 9          "field2-text": "secondField" 

In this example, the value of spec.field1 is field1-text.

1$ kubectl describe composite 2Name:         my-example-twx7n 3Spec: 4  # Removed for brevity 5  field1:         field1-text 

The annotation applied to the managed resource is firstField.

1$ kubectl describe bucket 2Name:         my-example-twx7n-ndb2f 3Annotations:  crossplane.io/composition-resource-name: bucket1 4              myAnnotation: firstField 5# Removed for brevity. 

Match transform

The match transform is like the map transform.

The match transform adds support for regular expressions along with exact strings and can provide default values if there isn’t a match.

A match object requires a patterns object.

The patterns is a list of one or more patterns to attempt to match the input value against.

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.field1  4    toFieldPath: metadata.annotations["myAnnotation"]  5    transforms:  6      - type: match  7        match:  8          patterns:  9            - type: literal 10              # Removed for brevity 11            - type: regexp 12              # Removed for brevity 

Match patterns can be either type: literal to match an exact string or type: regexp to match a regular expression.

Note
Crossplane stops processing matches after the first pattern match.

Match an exact string

Use a pattern with type: literal to match an exact string.

On a successful match Crossplane provides the result: to the patch toFieldPath.

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.field1  4    toFieldPath: metadata.annotations["myAnnotation"]  5    transforms:  6      - type: match  7        match:  8          patterns:  9            - type: literal 10              literal: "field1-text" 11              result: "matchedLiteral" 

Match a regular expression

Use a pattern with type: regexp to match a regular expression. Define a regexp key with the value of the regular expression to match.

On a successful match Crossplane provides the result: to the patch toFieldPath.

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.field1  4    toFieldPath: metadata.annotations["myAnnotation"]  5    transforms:  6      - type: match  7        match:  8          patterns:  9            - type: regexp 10              regexp: '^field1.*' 11              result: "foundField1" 

Using default values

Optionally you can provide a default value to use if there is no matching pattern.

The default value can either be the original input value or a defined default value.

Use fallbackTo: Value to provide a default value if a match isn’t found.

For example if the string unknownString isn’t matched, Crossplane provides the Value StringNotFound to the toFieldPath

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.field1  4    toFieldPath: metadata.annotations["myAnnotation"]  5    transforms:  6      - type: match  7        match:  8          patterns:  9            - type: literal 10              literal: "UnknownString" 11              result: "foundField1" 12          fallbackTo: Value 13          fallbackValue: "StringNotFound" 

To use the original input as the fallback value use fallbackTo: Input.

Crossplane uses the original fromFieldPath input for the toFieldPath value.

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.field1  4    toFieldPath: metadata.annotations["myAnnotation"]  5    transforms:  6      - type: match  7        match:  8          patterns:  9            - type: literal 10              literal: "UnknownString" 11              result: "foundField1" 12          fallbackTo: Input 

Math transforms

Use the math transform to multiply an input or apply a minimum or maximum value.

Important
A math transform only supports integer inputs.
1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.numberField 4    toFieldPath: metadata.annotations["mathAnnotation"] 5    transforms: 6      - type: math 7        math: 8          ... 

clampMin

The type: clampMin uses a defined minimum value if an input is larger than the type: clampMin value.

For example, this type: clampMin requires an input to be greater than 20.

If an input is lower than 20, Crossplane uses the clampMin value for the toFieldPath.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.numberField 4    toFieldPath: metadata.annotations["mathAnnotation"] 5    transforms: 6      - type: math 7        math: 8          type: clampMin 9          clampMin: 20 

clampMax

The type: clampMax uses a defined minimum value if an input is larger than the type: clampMax value.

For example, this type: clampMax requires an input to be less than 5.

If an input is higher than 5, Crossplane uses the clampMax value for the toFieldPath.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.numberField 4    toFieldPath: metadata.annotations["mathAnnotation"] 5    transforms: 6      - type: math 7        math: 8          type: clampMax 9          clampMax: 5 

Multiply

The type: multiply multiplies the input by the multiply value.

For example, this type: multiply multiplies the value from the fromFieldPath value by 2

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.numberField 4    toFieldPath: metadata.annotations["mathAnnotation"] 5    transforms: 6      - type: math 7        math: 8          type: multiply 9          multiply: 2 
Note
The multiply value only supports integers.

String transforms

The string transform applies string formatting or manipulation to string inputs.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.field1 4    toFieldPath: metadata.annotations["stringAnnotation"] 5    transforms: 6      - type: string 7        string: 8          type: ... 

String transforms support the following types

  • Convert
  • Format
  • Join
  • Regexp
  • TrimPrefix
  • TrimSuffix

String convert

The type: convert converts the input based on one of the following conversion types:

  • ToUpper - Change the string to all upper case letters.
  • ToLower - Change the string to all lower case letters.
  • ToBase64 - Create a new base64 string from the input.
  • FromBase64 - Create a new text string from a base64 input.
  • ToJson - Convert the input string to valid JSON.
  • ToSha1 - Create a SHA-1 hash of the input string.
  • ToSha256 - Create a SHA-256 hash of the input string.
  • ToSha512 - Create a SHA-512 hash of the input string.
  • ToAdler32 - Create an Adler32 hash of the input string.
1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.field1 4    toFieldPath: metadata.annotations["FIELD1-TEXT"] 5    transforms: 6      - type: string 7        string: 8          type: Convert 9          convert: "ToUpper" 

String format

The type: format applies Go string formatting to the input.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.field1 4    toFieldPath: metadata.annotations["stringAnnotation"] 5    transforms: 6      - type: string 7        string: 8          type: Format 9          fmt: "the-field-%s" 

Join

The type: Join joins all values in the input array into a string using the given separator.

This transform only works with array inputs.

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.parameters.inputList  4    toFieldPath: spec.targetJoined  5    transforms:  6      - type: string  7        string:  8          type: Join  9          join: 10            separator: "," 

Regular expression type

The type: Regexp extracts the part of the input matching a regular expression.

Optionally use a group to match a regular expression capture group. By default Crossplane matches the entire regular expression.

 1patches:  2  - type: FromCompositeFieldPath  3    fromFieldPath: spec.desiredRegion  4    toFieldPath: metadata.annotations["euRegion"]  5    transforms:  6      - type: string  7        string:  8          type: Regexp  9          regexp: 10            match: '^eu-(.*)-' 11            group: 1 

Trim prefix

The type: TrimPrefix uses Go’s TrimPrefix and removes characters from the beginning of a line.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.desiredRegion 4    toFieldPath: metadata.annotations["north-1"] 5    transforms: 6      - type: string 7        string: 8          type: TrimPrefix 9          trim: `eu- 

Trim suffix

The type: TrimSuffix uses Go’s TrimSuffix and removes characters from the end of a line.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.desiredRegion 4    toFieldPath: metadata.annotations["eu"] 5    transforms: 6      - type: string 7        string: 8          type: TrimSuffix 9          trim: `-north-1' 

Patch policies

Crossplane supports two types of patch policies:

  • fromFieldPath
  • toFieldPath

fromFieldPath policy

Using a fromFieldPath: Required policy on a patch requires the fromFieldPath to exist in the data source resource.

Tip
If a resource patch isn’t working applying the fromFieldPath: Required policy may produce an error in the composite resource to help troubleshoot.

By default, Crossplane applies the policy fromFieldPath: Optional. With fromFieldPath: Optional Crossplane ignores a patch if the fromFieldPath doesn’t exist.

With fromFieldPath: Required the composite resource produces an error if the fromFieldPath doesn’t exist.

1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.desiredRegion 4    toFieldPath: metadata.annotations["eu"] 5    policy: 6      fromFieldPath: Required 

toFieldPath policy

By default when applying a patch the function replaces the destination data. Use toFieldPath to allow patches to merge arrays and objects without overwriting them.

The toFieldPath policy supports these options:

PolicyAction
Replace (default)Replace the value at toFieldPath.
MergeObjectsRecursively merge into the value at toFieldPath. Keep any conflicting object keys.
ForceMergeObjectsRecursively merge into the value at toFieldPath. Replace any conflicting object keys.
MergeObjectsAppendArraysLike MergeObjects, but append values to arrays instead of replacing them.
ForceMergeObjectsAppendArraysLike ForceMergeObjects, but append values to arrays instead of replacing them.
1patches: 2  - type: FromCompositeFieldPath 3    fromFieldPath: spec.desiredRegion 4    toFieldPath: metadata.annotations["eu"] 5    policy: 6      toFieldPath: MergeObjectsAppendArrays 

Composite resource connection details

Function patch and Transform must define the specific secret keys a resource creates with the connectionDetails object.

Secret TypeDescription
FromConnectionSecretKeyCreate a secret key matching the key of a secret generated by the resource.
FromFieldPathCreate a secret key matching a field path of the resource.
FromValueCreate a secret key with a predefined value.
Note

The value type must use a string value.

The value isn’t added to the individual resource secret object. The value only appears in the combined composite resource secret.

 1kind: Composition  2spec:  3  mode: Pipeline  4  pipeline:  5  - step: patch-and-transform  6    functionRef:  7      name: function-patch-and-transform  8    input:  9      apiVersion: pt.fn.crossplane.io/v1beta1 10      kind: Resources 11      resources: 12      - name: key 13        base: 14          # Removed for brevity 15          spec: 16            forProvider: 17            # Removed for brevity 18            writeConnectionSecretToRef: 19              namespace: docs 20              name: key1 21        connectionDetails: 22          - name: my-username 23            type: FromConnectionSecretKey 24            fromConnectionSecretKey: username 25          - name: my-field-secret 26            type: FromFieldPath 27            fromFieldPath: spec.forProvider.user 28          - name: my-status-secret 29            type: FromValue 30            value: "docs.crossplane.io" 

The connectionDetails in a resource can reference a secret from a resource with FromConnectionSecretKey, from another field in the resource with FromFieldPath or a statically defined value with FromValue.

Crossplane sets the secret key to the name value.

Describe the secret to view the secret keys inside the secret object.

Tip

If more than one resource generates secrets with the same secret key name, Crossplane only saves one value.

Use a custom name to create unique secret keys.

Important

Crossplane only adds connection details listed in the connectionDetails to the combined secret object.

Any connection secrets in a managed resource, not defined in the connectionDetails aren’t added to the combined secret object.

 1kubectl describe secret  2Name:         my-access-key-secret  3Namespace:    default  4Labels:       <none>  5Annotations:  <none>  6  7Type:  connection.crossplane.io/v1alpha1  8  9Data 10==== 11myUsername:      20 bytes 12myFieldSecret:   24 bytes 13myStaticSecret:  18 bytes 
Note

The CompositeResourceDefinition can also limit which keys Crossplane stores from the composite resources.

By default an XRD writes all secret keys listed in the composed resources connectionDetails to the combined secret object.

For more information on connection secrets read about managed resources.

Resource readiness checks

By default function-patch-and-transform considers a composite resource as READY when the status of all created resource are Type: Ready and Status: True

Some resources, for example, a ProviderConfig, don’t have a Kubernetes status and are never considered Ready.

Custom readiness checks allow Compositions to define what custom conditions to meet for a resource to be Ready.

Tip
Use multiple readiness checks if a resource must meet multiple conditions for it to be Ready.

Define a custom readiness check with the readinessChecks field on a resource.

Checks have a type defining how to match the resource and a fieldPath of which field in the resource to compare.

1apiVersion: pt.fn.crossplane.io/v1beta1 2kind: Resources 3resources: 4- name: my-resource 5  base: 6    # Removed for brevity 7  readinessChecks: 8    - type: <match type> 9      fieldPath: <resource field> 

Compositions support matching resource fields by:

  • string match
  • integer match
  • non-empty match
  • always ready
  • condition match
  • boolean match

Match a string

MatchString considers the composed resource to be ready when the value of a field in that resource matches a specified string.

Note

Crossplane only supports exact string matches. Substrings and regular expressions aren’t supported in a readiness check.

For example, matching the string Online in the resource’s status.atProvider.state field.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: my-resource  5  base:  6    # Removed for brevity  7  readinessChecks:  8    - type: MatchString  9      fieldPath: status.atProvider.state 10      matchString: "Online" 

Match an integer

MatchInteger considers the composed resource to be ready when the value of a field in that resource matches a specified integer.

Note

Crossplane doesn’t support matching 0.

For example, matching the number 4 in the resource’s status.atProvider.state field.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: my-resource  5  base:  6    # Removed for brevity  7  readinessChecks:  8    - type: MatchInteger  9      fieldPath: status.atProvider.state 10      matchInteger: 4 

Match that a field exists

NonEmpty considers the composed resource to be ready when a field exists with a value.

Note

Crossplane considers a value of 0 or an empty string as empty.

For example, to check that a resource’s status.atProvider.state field isn’t empty.

1apiVersion: pt.fn.crossplane.io/v1beta1 2kind: Resources 3resources: 4- name: my-resource 5  base: 6    # Removed for brevity 7  readinessChecks: 8    - type: NonEmpty 9      fieldPath: status.atProvider.state 
Tip
Checking NonEmpty doesn’t require setting any other fields.

Always consider a resource ready

None considers the composed resource to be ready as soon as it’s created. Crossplane doesn’t wait for any other conditions before declaring the resource ready.

For example, consider my-resource ready as soon as it’s created.

1apiVersion: pt.fn.crossplane.io/v1beta1 2kind: Resources 3resources: 4- name: my-resource 5  base: 6    # Removed for brevity 7  readinessChecks: 8    - type: None 

Match a condition

Condition considers the composed resource to be ready when it finds the expected condition type, with the expected status for it in its status.conditions.

For example, consider my-resource, which is ready if there is a condition of type MyType with a status of Success.

 1apiVersion: pt.fn.crossplane.io/v1beta1  2kind: Resources  3resources:  4- name: my-resource  5  base:  6    # Removed for brevity  7  readinessChecks:  8    - type: MatchCondition  9      matchCondition: 10        type: MyType 11        status: Success 

Match a boolean

Two types of checks exist for matching boolean fields:

  • MatchTrue
  • MatchFalse

MatchTrue considers the composed resource to be ready when the value of a field inside that resource is true.

MatchFalse considers the composed resource to be ready when the value of a field inside that resource is false.

For example, consider my-resource, which is ready if status.atProvider.manifest.status.ready is true.

1apiVersion: pt.fn.crossplane.io/v1beta1 2kind: Resources 3resources: 4- name: my-resource 5  base: 6    # Removed for brevity 7  readinessChecks: 8    - type: MatchTrue 9      fieldPath: status.atProvider.manifest.status.ready 
Tip
Checking MatchTrue doesn’t require setting any other fields.

MatchFalse matches fields that express readiness with the value false.

For example, consider my-resource, is ready if status.atProvider.manifest.status.pending is false.

1apiVersion: pt.fn.crossplane.io/v1beta1 2kind: Resources 3resources: 4- name: my-resource 5  base: 6    # Removed for brevity 7  readinessChecks: 8    - type: MatchFalse 9      fieldPath: status.atProvider.manifest.status.pending 
Tip
Checking MatchFalse doesn’t require setting any other fields.
Crossplane logo
Twitter
Youtube
Podcast
Forum

© Crossplane Authors 2025. Documentation distributed under CC-BY-4.0.

© 2025 The Linux Foundation. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page.

cncfLogo

We are a Cloud Native Computing Foundation incubating project.