How AI is applied across API Evangelist and APIs.io. Read my AI disclosure →
API Evangelist API Evangelist
Discovery
Learnings
Guidance
Toolbox
Alignment
API Evangelist LLC

Crossplane v2.2 — More Capable, More Reliable, More Observable

calendar_today March 17, 2026 person Adam Wolfe Gordon domain crossplane
Crossplane v2.2 — More Capable, More Reliable, More Observable

Crossplane v2.2 — More Capable, More Reliable, More Observable<p>
We are excited to announce that Crossplane v2.2.0 has been released and is now available for installation into your control planes. This release is a regular quarterly release focused on maturing key areas of functionality across the project, as Crossplane continues to become more capable, more reliable, and more performant for your production workloads. In this post, we'll dive into the highlights.</p><hr /><h2 id="debugging-with-the-pipeline-inspector-alpha">Debugging with the Pipeline Inspector (Alpha)</h2><p>Composition functions give platform builders the power to express arbitrarily complex resource generation logic, but debugging that logic inside a running control plane has historically been difficult. You can write tests and use crossplane render locally, but viewing the requests are going into each function step and the responses coming out required updating the pipeline or the functions themselves.</p><p>Crossplane v2.2 introduces a new alpha feature to address this: the pipeline inspector. When enabled, the inspector intercepts every function request and response in a composition pipeline and forwards them over gRPC to a user-configured socket path. This opens the door to a range of debugging and observability use cases — from a local observer that dumps requests to stdout during development, to a production-grade system that stores pipeline traces for auditing or troubleshooting.</p><p>The pipeline inspector is disabled by default. To enable it, pass the --enable-pipeline-inspector flag to Crossplane. The default socket address is /var/run/pipeline-inspector/socket, which can be overridden by passing the --pipeline-inspector-socket flag. The full Helm values required to enable the inspector and run a basic pipeline logging sidecar are:</p><pre># Enable the pipeline inspector feature flag args:

  • –enable-pipeline-inspector
  • –pipeline-inspector-socket=/var/run/pipeline-inspector/socket

Inject the pipeline inspector sidecar

sidecarsCrossplane:

  • name: pipeline-inspector image: xpkg.crossplane.io/crossplane/inspector-sidecar:v0.0.3 args:
    • –socket-path=/var/run/pipeline-inspector/socket
    • –max-recv-msg-size=8388608 # 8MB volumeMounts:
    • name: pipeline-inspector-socket mountPath: /var/run/pipeline-inspector resources: requests: cpu: 10m memory: 64Mi limits: cpu: 100m memory: 128Mi

Add the shared volume for Unix socket communication

extraVolumesCrossplane:

  • name: pipeline-inspector-socket emptyDir: {}

extraVolumeMountsCrossplane:

  • name: pipeline-inspector-socket mountPath: /var/run/pipeline-inspector</code></pre><p>With this configured, Crossplane will forward a copy of each RunFunctionRequest and RunFunctionResponse to the inspector sidecar as the pipeline runs, giving you full visibility into the data flowing through your function pipeline. This feature remains Alpha in v2.2 and will continue to be matured in future releases.</p><hr /><h2 id="runtime-configuration-for-package-dependencies">Runtime Configuration for Package Dependencies</h2><p>Previously, if you needed to configure a package's runtime you had to set a runtimeConfigRef directly on each package resource. This worked for explicitly installed packages, but had no effect on packages installed as dependencies. This made it difficult to leverage Configuration packages as a top-level construct.</p><p>ImageConfig, introduced in Crossplane v1.18, has grown into a powerful centralized mechanism for configuring package installation. New in v2.2, ImageConfig can configure the DeploymentRuntimeConfig used by packages matching a given image prefix, including packages installed as dependencies. The new spec.runtime.configRef field lets you specify a runtime configuration and it applies to all matching packages regardless of how they are installed.</p><p>Consider a scenario where you're running on Azure and need your provider pods to use Azure Workload Identity. Previously, you might have disabled dependency resolution to install the provider manually. Now you can express this intent once, declaratively:</p><pre>--- apiVersion: pkg.crossplane.io/v1beta1 kind: ImageConfig metadata: name: azure-workload-identity spec: matchImages:
    • prefix: xpkg.crossplane.io/crossplane-contrib/provider-azure-
    • prefix: xpkg.crossplane.io/crossplane-contrib/provider-family-azure runtime: configRef: name: azure-workload-identity

apiVersion: pkg.crossplane.io/v1beta1 kind: DeploymentRuntimeConfig metadata: name: azure-workload-identity spec: serviceAccountTemplate: metadata: annotations: azure.workload.identity/client-id: "12345678-1234-1234-1234-123456789012" deploymentTemplate: metadata: labels: azure.workload.identity/use: "true" spec: selector: {} template: metadata: labels: azure.workload.identity/use: "true" spec: containers: - name: package-runtime args: []</code></pre><p>With this ImageConfig in place, all Azure family providers — whether installed explicitly or as dependencies — will get the azure-workload-identity runtime configuration applied, and therefore have Workload Identity configured on their service accounts. Note that a matching ImageConfig runtime takes precedence over any runtimeConfigRef specified directly on a package's spec.</p><p>To confirm the configuration was applied, check the appliedImageConfigRefs field in the package revision's status:</p><pre>$ kubectl get providerrevision crossplane-contrib-provider-family-azure-e57d1e7b1ce7 -o yaml

status: appliedImageConfigRefs:

  • name: azure-workload-identity reason: ConfigureRuntime

    </code></pre><hr /><h2 id="xrd-validation-beyond-the-spec">XRD Validation Beyond the Spec</h2><p>Crossplane XRDs let you define rich OpenAPI schemas for the resources your platform users create. Until now, x-kubernetes-validations (CEL validation rules) could only be used to validate fields within the spec of a composite resource. This left a real gap for platform builders who wanted to enforce naming conventions, require specific labels, or validate other metadata properties at admission time.</p><p>Crossplane v2.2 closes this gap by allowing XRDs to configure x-kubernetes-validations outside of spec. This lets you write CEL rules that validate things like the resource's name format or required label values and provide a more complete API contract for your composite resources.</p><p>For example, suppose your platform requires all XR names to follow a specific pattern. You can now enforce this directly in the XRD:</p><pre>apiVersion: apiextensions.crossplane.io/v1 kind: CompositeResourceDefinition metadata: name: databases.platform.example.org spec: group: platform.example.org names: kind: Database plural: databases versions:

    • name: v1alpha1 served: true referenceable: true schema: openAPIV3Schema: type: object x-kubernetes-validations: - rule: "self.metadata.name.startsWith('db-')" message: "Database names must start with 'db-'" properties: spec: type: object properties: region: type: string</code></pre><p>Any attempt to create an Database with a name that doesn't start with db- will now be rejected at the Kubernetes API server level, giving your users clear, immediate feedback rather than a confusing reconciliation error later.</p><hr /><h2 id="using-openapi-schemas-in-functions">Using OpenAPI Schemas in Functions</h2><p>Composition and operation functions may wish to know the OpenAPI schemas for the resources they're working with, for example to make schema-aware decisions, validate resources, or dynamically generate resources. Previously a function could indirectly get the OpenAPI schema for a CRD by requesting the CRD as a RequiredResource (or ExtraResource in Crossplane 1.x). However, schemas were not available for built-in Kubernetes kinds and some manipulation was necessary to extract the OpenAPI schema from the CRD.</p><p>Crossplane v2.2 introduces RequiredSchemas in the RunFunctionResponse, allowing functions to request schemas. Analogous to RequiredResources, a function can populate the new field with the API group/version/kind of any resources whose OpenAPI schema it needs and on the next reconciliation Crossplane will include the requested schemas in the function request.</p><p>With this expansion of the function gRPC API, Crossplane v2.2 also introduces capability advertisement. The RunFunctionRequest now includes a Capabilities field that tells the function what the running version of Crossplane supports. For example, a function that can optionally use OpenAPI schemas may check whether Capabilities contains CAPABILITY_REQUIRED_SCHEMAS to determine whether schemas are available.</p><hr /><h2 id="improvements-to-crossplane-beta-trace">Improvements to crossplane beta trace</h2><p>Many platform engineers use the crossplane beta trace command is a to understand the state of resources in a Crossplane control plane. v2.2 ships two significant enhancements to make it even more useful.</p><p>Trace all resources of a given kind. Previously, crossplane beta trace could take only a single resource instance. Now you can pass a kind (and optionally a namespace) to trace all resources of that type at once. This is helpful when you want to quickly understand the health of every Database or every Provider in your cluster:</p><pre># Trace all Database resources in the platform namespace crossplane beta trace databases.platform.example.org -n platform

Trace all Providers

crossplane beta trace providers</code></pre><p>Watch mode. The trace command now supports a --watch flag (shorthand -w), which keeps the trace output live and refreshes it as resources change, similar to kubectl get --watch. This is especially useful during debugging sessions when you're waiting for a resource to reconcile and want to see the dependency tree update in real time:</p><pre>crossplane beta trace databases.platform.example.org db-production --watch</pre><hr /><h2 id="notable-breaking-changes">Notable Breaking Changes</h2><p>Before upgrading, be aware of two breaking changes in v2.2:</p><p>Function input CRDs are no longer installed. Input CRDs included in Function packages are no longer installed by the package manager, following the xpkg specification. Additionally, unknown or disallowed resource types within a package are now silently ignored instead of causing package installation to fail.</p><p>Package cache on-disk structure has changed. The internal structure of the package cache has been updated. This breaks an undocumented behavior that allowed packages to be "side-loaded" directly into Crossplane, which was sometimes used for testing. If you relied on this behavior, please see #6981 and #7147 for details on the necessary changes.</p><hr /><h2 id="get-involved">Get Involved</h2><p>We love contributions from the community in any form: code contributions, issues, questions, feedback on proposals, and many more. Whether you are a developer, user, or just interested in what we're up to, feel free to join us via one of the following methods:</p><ul><li>Crossplane website</li><li>GitHub</li><li>Slack</li><li>LinkedIn</li><li>YouTube</li><li>Reddit</li><li>Email</li><li>Attend a community meeting</li></ul>

open_in_new Read original post