Upgrade Crossplane v2 to Upbound Crossplane
This guide explains how to upgrade a control plane you run from the Open-Source version of Crossplane v2 to Upbound Crossplane (UXP).
Upbound Crossplane (UXP) is the AI-native distribution of Crossplane by Upbound. UXP builds on Crossplane v2.0 and maintains full compatibility with open source Crossplane. Use this guide when you want to upgrade to gain enhanced stability and features like improved package management and observability. Once you've upgraded, this guide also connects your control plane to a Hub for centralized visibility across every control plane you run.
To try the upgrade on local kind clusters first, follow the upgrade quickstart.
Prerequisites
To upgrade to Upbound Crossplane, your control plane must be running Crossplane v2.0.1 or greater.
To upgrade an older version of Crossplane, refer to the Crossplane upgrade documentation and come back to this guide when your control plane is v2.0.1 or greater.
To determine your Crossplane version, use the crossplane CLI and look for the
Server Version:
crossplane version
Client Version: v2.3.4
Server Version: v2.3.4
Before you begin, make sure you have:
- An actively supported Kubernetes version
- An existing OSS Crossplane installation on one of the versions in the version compatibility table below
kubectlconfigured to access your cluster- Helm version
v3.2.0or later - Cluster admin permissions
- A Commercial license key (for Commercial features only)
Upbound recommends backing up your critical resources before beginning this process.
Version compatibility and breaking changes
Make sure you understand the version compatibility and breaking changes before you begin your upgrade.
Version compatibility
When upgrading from OSS Crossplane, the target UXP version must match the Crossplane version up to the -up.N suffix:
- ❌ Crossplane
v2.3.4→ UXPv2.4.0-up.N - ✅ Crossplane
v2.3.4→ UXPv2.3.4-up.N
Find the row matching your Crossplane version and use its UXP version for
UXP_VERSION in the upgrade steps below:
| Crossplane version | UXP version |
|---|---|
| v2.1.x | 2.1.8-up.2 |
| v2.2.x | 2.2.4-up.2 |
| v2.3.x | 2.3.4-up.2 |
See the UXP release notes for the full list of patch releases within each line.
To upgrade an older version of Crossplane to UXP, upgrade Crossplane first and return when your control plane matches the version of UXP.
Breaking change You must now specify fully qualified package URLs:
- ❌
package: provider-aws:v0.34.0 - ✅
package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.34.0
Using fully qualified images was already a best practice, but Crossplane now enforces this practice to avoid confusion and unexpected behavior. This ensures users know which registry their packages use.
Before upgrading to Upbound Crossplane, please ensure all your Packages are
using fully qualified images that explicitly specify a registry
(registry.example.com/repo/package:tag).
Verify packages and backup Crossplane resources
Prepare your environment for upgrade by verifying package configurations and creating backups.
-
Review your existing Crossplane packages:
# Check existing packages for fully qualified imageskubectl get pkgThe output should look like the following:
NAME INSTALLED HEALTHY PACKAGEprovider.pkg.crossplane.io/upbound-provider-aws-s3 True True xpkg.upbound.io/upbound/provider-aws-s3:v1.21.1provider.pkg.crossplane.io/upbound-provider-family-aws True True xpkg.upbound.io/upbound/provider-family-aws:v2.0.1 -
Review your existing Crossplane resources:
# Backup all Crossplane configurationskubectl get configurations.pkg -o yaml > configurations-backup.yamlkubectl get providers.pkg -o yaml > providers-backup.yamlkubectl get functions.pkg -o yaml > functions-backup.yaml# Backup your composite and managed resourceskubectl get composite -A -o yaml > composites-backup.yamlkubectl get managed -o yaml > managed-resources-backup.yaml -
Verify your current Crossplane version and health:
# Check current versionhelm list -n crossplane-system# Verify all resources are healthykubectl get configurations.pkgkubectl get providers.pkgkubectl get functions.pkgExpected healthy state:
- Configurations:
INSTALLED: True,HEALTHY: True - Providers:
INSTALLED: True,HEALTHY: True - Functions:
INSTALLED: True,HEALTHY: True - Composite resources:
SYNCED: True,READY: True
- Configurations:
-
Capture your critical cluster workloads that depend on Crossplane to plan for minimal disruption.
Create a ClusterAdmin
Grant your control plane the ability to create the necessary Kubernetes resources.
-
Create a ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: crossplane-clusteradminroleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cluster-adminsubjects:- kind: ServiceAccountname: crossplanenamespace: crossplane-system -
Save as
rbac.yamland apply it:kubectl apply -f rbac.yaml
The ClusterRoleBinding gives full admin access to Crossplane. While this is fine for development purposes, it's advised for production scenarios to be diligent in what permissions you grant Crossplane. Only give it what's necessary to create and manage the resources you need it to.
Upgrade to UXP
Moving from open source Crossplane to UXP v2 provides production level
enterprise features like ProviderVPA, Knative, and enterprise support.
Applying a Commercial license unlocks those features. Review our pricing plans
for more information.
-
Set the UXP version to install. Replace the value with the version matching your Crossplane version from the version compatibility table above:
-
Choose your upgrade method and run the upgrade:
- Helm Install
- Up CLI
Add the Upbound repository and upgrade your Crossplane cluster:
helm repo add upbound-stable https://charts.upbound.io/stable && helm repo update
helm upgrade --install crossplane --namespace crossplane-system upbound-stable/crossplane --version "${UXP_VERSION}"
First, download the CLI:
curl -sL "https://cli.upbound.io" | sh
Next, upgrade your Crossplane cluster to UXP:
up uxp upgrade "${UXP_VERSION}"
-
Install your Commercial license:
up uxp license apply /path/to/license.jsonWithout a license, UXP runs with commercial features locked. You can apply a license at any time after the upgrade.
Verify your upgrade
-
Check that all resources are healthy:
helm list -n crossplane-systemkubectl get configurations.pkgkubectl get providers.pkgkubectl get functions.pkgkubectl get composite -Akubectl get managedhelm listnow shows the-up.Nchart. Everything else reports the same healthy state it did before the upgrade. -
Verify your commercial features (Commercial only):
After applying the license, check for
VPAresources:kubectl -n crossplane-system get vpaProvider revisions should be healthy:
kubectl get providerrevisions.pkg -
Verify function revision runtime update (Commercial only):
Function revisions should show healthy runtime status:
kubectl get functionrevisions.pkgExpected output:
NAME HEALTHY RUNTIME IMAGE STATE AGEcrossplane-contrib-function-auto-ready-35bfe51b9ce9 True True xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.5.0 Active 16mcrossplane-contrib-function-patch-and-transform-d000d8ce634a True True xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.9.0 Active 17m
Create or choose a Hub
The Hub gives you one API and Console for every control plane you run, including the one you just upgraded. If your organization already runs a Hub, whether Upbound Cloud or self-hosted, skip to Connect your control plane to the Hub.
To stand up a new self-hosted Hub, follow the Hub installation guide. It walks through the Postgres, OIDC, and Gateway prerequisites a production install needs. Upbound Cloud customers already have a Hub, so sign in to the Console instead of installing one.
Connect your control plane to the Hub
Register the control plane you just upgraded, then deploy hub-connector to
sync its resources into the Hub.
-
In the Console, open the Control Planes view, select Register Control Plane, and choose a realm and name for this control plane. The Console shows a registration token once, so copy it now.
-
Set the token and your control plane's kubeconfig context:
export REGISTRATION_TOKEN=<paste-registration-token>export CONTROL_PLANE_CONTEXT=<control-plane-context> -
Create a namespace and a secret holding the token:
kubectl --context="$CONTROL_PLANE_CONTEXT" create namespace upbound-systemkubectl --context="$CONTROL_PLANE_CONTEXT" --namespace upbound-system \create secret generic hub-connector-credentials \--from-literal=registrationToken="$REGISTRATION_TOKEN" -
Install the connector, pointing it at your Hub:
helm install hub-connector oci://xpkg.upbound.io/upbound/hub-connector \--kube-context "$CONTROL_PLANE_CONTEXT" \--namespace upbound-system \--set connector.hub.url=<hub-url> -
Confirm the connector reaches
Ready:kubectl --context="$CONTROL_PLANE_CONTEXT" --namespace upbound-system \wait --for=condition=Ready pod \--selector app.kubernetes.io/name=hub-connector --timeout=120sA connector stuck in
CrashLoopBackOffwith aconnection refusederror can't reachconnector.hub.url. A rejected registration token means the Hub already consumed it, so reissue the token in the Console and replace the secret. -
Open the Console's control planes view. This control plane shows a status of Ready, and its resources view lists what UXP now manages, including the packages and composite resources that came through the upgrade.
See Connect a control plane for the kubectl-only path, troubleshooting steps, and how to scope which resources the connector syncs.
Next steps
After upgrading to Upbound Crossplane, try out these features:
- The developer experience improvements with our builders workshop
- Browse all your managed resources with the Crossplane Web UI
- Query resource states in real-time with Upbound Query API
- Leverage Intelligent Control Planes to Dynamically scale an RDS Instance
- Join the #Upbound channel on the Crossplane Slack for questions and support
- Access management to grant users and groups access to your control plane in the Hub