Skip to content

Banner image Banner image

Crossplane v2: API-first platforms and compositional control planes

Crossplane v2 announced at KubeCon EU 2026 marks a significant shift from treating infrastructure provisioning as a secondary feature to treating API-first composition as the foundational architecture for platform teams.

The keynote demos and sessions showed that the problem Crossplane solves is not "how do we provision cloud resources from Kubernetes" but rather "how do we let application teams safely self-serve infrastructure without losing governance, cost control, or risk management."

Quick takeaways

  • Control planes are composable: Teams no longer need a single monolithic Crossplane instance; they can design specialised control planes (one for databases, one for networking, one for observability) that compose cleanly together
  • Project workflows reduce cognitive load: The new project model lets teams define "this is a Postgres database for this app in this env" as a single API call rather than juggling Compositions, Claims, and XRDs
  • Observability is built-in, not bolted-on: v2 ships with better status conditions, clearer error messages, and deeper insights into what the control plane is actually doing (not just success/failure)
  • Governed autonomy becomes achievable: With proper composition and observability, platform teams can grant self-service access to application teams without sacrificing safety or auditability

Crossplane v2 composable control planes Crossplane v2 composable control planes

What was getting in the way

Crossplane v1 gave platform teams the capability to build self-service infrastructure APIs but required them to reason about:

  1. Complex composition chains — XRDs, Compositions, Claims, and Claims were powerful but cognitive overhead was high
  2. Monolithic architecture — A single control plane had to handle databases, networking, storage, observability connections, compliance scanning; adding a new capability meant adding to an already-complex system
  3. Poor observability of intent — Status conditions told you if provisioning succeeded but not why a user's request took certain paths through the Composition chain
  4. Tight coupling of APIs to implementation — If you wanted to shift from AWS to multi-cloud, or from cloud-managed to self-hosted, the API user experienced disruption

RBI's migration from v1 to v2 (covered in From GitOps to AIOps in regulated environments) showed how teams were working around these constraints with sharded topologies and risk-differentiated execution layers.

Composable control planes: specialisation, not one-size-fits-all

The biggest architectural shift in v2 is moving from "one Crossplane instance manages everything" to "compose multiple control planes that each own one domain."

Example topology:

App Team Claims
Platform API Layer (Kubernetes)
  ┌──┴──┬──────┬──────────┐
  ↓     ↓      ↓          ↓
 DB   Network Storage  Observability
 CP    CP      CP         CP
  ↓     ↓      ↓          ↓
AWS   Azure   GCP    Cloud-native

Why this matters: - Single responsibility: The database control plane doesn't need to know about networking concerns; the network control plane doesn't concern itself with storage - Independent scaling: Networking changes don't require a release cycle for the database control plane - Cleaner error diagnosis: When a database provisioning request fails, you're looking at one control plane's logic, not a 2000-line Composition chain - Team ownership: Infrastructure teams can own the control planes they specialise in; they don't need to understand the entire stack

For RBI's regulated environment (with namespace/cluster/cloud-account isolation), composable control planes mean: - A sharding control plane that owns "which namespace/cluster/account should this request go to" - Specialised control planes in each shard (one per region, risk class, or compliance domain) - Application teams see a single API that abstracts away the complexity

Project workflows: simplifying the user experience

Crossplane v1 asked users to understand: - XRD (Composite Resource Definition): "Here's the shape of what you can provision" - Composition: "Here's the logic for turning your request into cloud resources" - Claim: "Here's your reference to the provisioned resource"

Crossplane v2's project model flattens this:

apiVersion: apiextensions.crossplane.io/v1beta1
kind: Project
metadata:
  name: customer-db-postgres
spec:
  description: "Self-service Postgres for customer data"
  owner: platform-team
  composition:
    ref:
      name: postgres-standard-aws
    options:
      region: eu-west-1
      retention: 30d
  safety:
    requireApproval: true
    auditLog: true
---
# Now a user just does:
apiVersion: customer-db-postgres
kind: Database
metadata:
  name: production-v1
spec:
  size: large
  backup: daily

This works because: - Single API: One call to provision, not three - Clear intent: The request describes what you want, not how to build it - Reduced cognitive load: Users don't learn Crossplane; they learn your platform's vocabulary

For Sony's platform team (covered in Platform engineering is a sociotechnical problem), this is critical: the easier you make self-service, the fewer workarounds and bypasses your users create.

Observability: understanding control plane decisions

Crossplane v1 told you: "Your Composition succeeded" or "Your Composition failed." It didn't explain why the Composition took certain paths.

Crossplane v2 ships with:

  1. Rich status conditions: Each step in a Composition is now a discrete condition you can observe

    status:
      conditions:
      - type: Ready
        status: "True"
      - type: CompositionReady
        status: "True"
      - type: ResourcesHealthy
        status: "True"
      - type: ValidationPassed
        status: "True"
      - type: SecurityScanCompleted
        status: "True"
        reason: Passed
    

  2. Event streams: Every decision point emits an event so you can trace the request flow

  3. Deep metrics: Control plane authors emit custom metrics that make it easy to answer "why did this take 45 seconds" or "which Compositions are failing most often"

Why this matters for AIOps (as RBI showed with their review layer): - AI systems need to understand why a resource provisioning failed to give good advice - Seeing only "failed, status=error" is not enough; you need to know which validation rule failed, which cloud API was unreachable, which cost threshold was exceeded - With v2's observability, an AI system can tell the user the actual constraint they hit, not just the failure

Risk-aware APIs: encoding constraints in the control plane

Crossplane v2's composition model makes it natural to express risk-differentiated execution:

apiVersion: composition.crossplane.io/v1
kind: Composition
metadata:
  name: database-multi-tier
spec:
  resources:
  # Tier 1: Production-grade (requires approval, full backup)
  - name: prod-db
    if:
      - matchLabels:
          risk-tier: production
    patches:
      - fromFieldPath: spec.size
        toFieldPath: spec.instanceSize
      - fromFieldPath: spec.retention
        toFieldPath: spec.backupRetentionDays
          value: 30
          min: 30
    readinessChecks:
      - type: MatchCondition
        matchCondition:
          status: "True"
          type: Ready

  # Tier 2: Staging (automatic backup, 7-day retention)
  - name: staging-db
    if:
      - matchLabels:
          risk-tier: staging
    patches:
      - fromFieldPath: spec.size
        toFieldPath: spec.instanceSize
      - toFieldPath: spec.backupRetentionDays
        value: 7
    readinessChecks:
      - type: MatchCondition
        matchCondition:
          status: "True"
          type: Ready

  # Tier 3: Ephemeral (point-in-time recovery only, 3-day retention)
  - name: dev-db
    if:
      - matchLabels:
          risk-tier: dev
    patches:
      - fromFieldPath: spec.size
        toFieldPath: spec.instanceSize
      - toFieldPath: spec.backupRetentionDays
        value: 3

This is how RBI handles infrastructure isolation without requiring different APIs for different risk classes. The user says "I need a database" and the control plane says "OK, what risk tier?" and then applies the right constraints.

API stability through composition, not breaking changes

In Crossplane v1, if you wanted to shift from AWS RDS to Azure Database for PostgreSQL, you often needed to rewrite the Composition and potentially the Claims.

Crossplane v2's composition-first design makes implementation abstraction easier:

# Platform team can layer abstractions
apiVersion: composition.crossplane.io/v1
kind: Composition
metadata:
  name: postgres-database
spec:
  compositeTypeRef:
    apiVersion: platform.example.com/v1
    kind: Database
  resources:
  # Internal selector: which provider to use
  - name: postgres-aws
    if:
      - matchLabels:
          provider: aws
    base:
      apiVersion: rds.aws.upbound.io/v1beta1
      kind: Instance
  - name: postgres-azure
    if:
      - matchLabels:
          provider: azure
    base:
      apiVersion: dbforpostgresql.azure.upbound.io/v1beta1
      kind: Server

Users always request:

apiVersion: platform.example.com/v1
kind: Database
metadata:
  name: my-db
spec:
  size: large

Platform team controls routing (via labels), so they can: - Migrate from AWS to Azure without breaking user APIs - Split new requests to different providers for load balancing - Gradually roll out cost optimizations

Practical action items

  1. Map your current infrastructure APIs — What do your users actually ask for? (Not "EC2 instances" but "web app deployment," "Postgres for our service," "observability pipeline")
  2. Design control planes around domains, not cloud providers — Create one per infrastructure type (databases, networking, storage, observability, compliance) not per cloud
  3. Invest in observability before deploying — Rich status conditions and event streams are v2's superpower; use them
  4. Start with one Composition per user request pattern — Don't build a 2000-line mega-Composition; start small and refactor
  5. Use risk labels to encode constraints — Let the control plane answer "what checks does this tier need?" rather than having users guess
  6. Test against user mental models — Does your Composition's logic match how users think about the problem? If not, simplify
  7. Build audit trails early — Who requested what, when, and why? Crossplane v2's event streams make this natural
  8. Version your Compositions — Treat them like software; test changes, have backwards compatibility strategy, plan deprecations
  9. Automate composition updates — As you refine your Compositions, use tooling to push updates safely (ArgoCD, FluxCD, or custom operators)
  10. Measure adoption and friction — Which Compositions see the most requests? Which get abandoned? Use metrics to guide refinement

Tying it together: platforms are products

Crossplane v2's shift toward project workflows, composable control planes, and observability is fundamentally about treating infrastructure APIs as a product rather than a mechanics problem.

This aligns directly with the platform teams are product teams synthesis: the easier you make self-service (project workflows), the fewer surprises users experience (composable control planes mean transparent reasoning), the better you diagnose when things go wrong (v2 observability), and the more confidently you can grant autonomy (risk-aware compositions).

See also: - From GitOps to AIOps in regulated environments — How RBI uses Crossplane v2 as part of their risk-aware promotion pipeline - Building self-service platforms with Crossplane v2.0 — Original KubeCon session highlights - KubeCon EU 2026 event notes — Full conference coverage