Merge pull request #976 from negz/guidance

Guide for updating v1 -> v2
This commit is contained in:
Nic Cope 2025-08-15 14:22:53 -07:00 committed by GitHub
commit 3b8bad4228
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 784 additions and 14 deletions

View File

@ -0,0 +1,387 @@
---
title: Upgrade to Crossplane v2
weight: 410
description: "Upgrade from Crossplane v1 to v2"
---
Crossplane v2 introduces significant improvements while maintaining backward
compatibility with most v1 configurations. This guide helps you upgrade from
Crossplane v1.x to v2.
Learn about [new features in Crossplane v2]({{<ref "../whats-new">}}) including
namespaced resources, the ability to compose any Kubernetes resource, and new
operational workflows.
{{<hint "important">}}
Only upgrade to Crossplane v2 from Crossplane v1.20, the final v1.x release.
If you're running an earlier version, upgrade to v1.20 first.
{{</hint>}}
{{<hint "note">}}
There's no automated tooling yet to migrate existing v1 cluster-scoped XRs and
MRs to v2 namespaced style. You can upgrade to Crossplane v2 and
start using the new namespaced features right away - your existing v1
resources continue working unchanged. See
[crossplane/crossplane#6726](https://github.com/crossplane/crossplane/issues/6726)
for migration tooling progress.
{{</hint>}}
## Prerequisites
Before upgrading, ensure:
* You're running Crossplane v1.20
* You're not using deprecated features (see [removed features](#removed-features))
* All packages use fully qualified image names
* [Helm](https://helm.sh/docs/intro/install/) version v3.2.0 or later
## Removed features
Crossplane v2 removes these deprecated features:
* [Native patch and transform composition](#native-patch-and-transform-composition)
* [ControllerConfig type](#controllerconfig-type)
* [External secret stores](#external-secret-stores)
* [Default registry flag](#default-registry-flag)
### Native patch and transform composition
**Deprecated in**: v1.17
**Replaced by**: [Composition functions]({{<ref "../composition/compositions">}})
If you're using `spec.mode: Resources` in your Compositions, migrate to
composition functions before upgrading.
**Migration help**: use the Crossplane v1.20 CLI to automatically convert your
Compositions:
```shell
# Convert patch and transform to function pipelines
crossplane beta convert pipeline-composition old-composition.yaml -o new-composition.yaml
```
<!-- vale Google.Headings = NO -->
### ControllerConfig type
<!-- vale Google.Headings = YES -->
**Deprecated in**: v1.11
**Replaced by**: [DeploymentRuntimeConfig]({{<ref "../packages/providers#runtime-configuration">}})
Update any ControllerConfig resources to use DeploymentRuntimeConfig instead.
**Migration help**: use the Crossplane v1.20 CLI to automatically convert your
ControllerConfigs:
```shell
# Convert ControllerConfig to DeploymentRuntimeConfig
crossplane beta convert deployment-runtime controller-config.yaml -o deployment-runtime-config.yaml
```
### External secret stores
**Status**: alpha feature, unmaintained
If you're using external secret stores, migrate to native Kubernetes secrets
or [External Secrets Operator](https://external-secrets.io/latest/) before upgrading.
### Default registry flag
**Removed**: `--registry` flag for default package registry
All packages must now use fully qualified names including the registry
host name. Check your packages with:
```shell
kubectl get pkg -o wide
```
Update any packages without registry host names before upgrading. For example:
- ❌ `crossplane-contrib/provider-aws-s3:v1.23.0`
- ✅ `xpkg.crossplane.io/crossplane-contrib/provider-aws-s3:v1.23.0`
## Who can upgrade
You can upgrade to Crossplane v2 if you meet these criteria:
* ✅ Running Crossplane v1.20
* ✅ Not using native patch and transform composition
* ✅ Not using ControllerConfig resources
* ✅ Not using external secret stores
* ✅ All packages use fully qualified image names
If you're using any removed features, migrate away from them first.
## Upgrade approach
The recommended upgrade approach:
1. [Prepare for upgrade](#1-prepare-for-upgrade)
2. [Upgrade Crossplane core](#2-upgrade-crossplane-core)
3. [Configure managed resource activation policies](#3-configure-managed-resource-activation-policies)
4. [Upgrade providers](#4-upgrade-providers)
5. [Start using v2 features](#5-start-using-v2-features)
### 1. Prepare for upgrade
Review your cluster for [removed features](#removed-features) and address any
that you're using. Each removed feature section includes commands to inspect
your cluster and migration tools to help convert resources.
### 2. Upgrade Crossplane core
Add the Crossplane Helm repository:
```shell
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
```
Upgrade to Crossplane v2:
```shell
helm upgrade crossplane \
--namespace crossplane-system \
crossplane-stable/crossplane
```
Verify the upgrade:
```shell
kubectl get pods -n crossplane-system
```
### 3. Configure managed resource activation policies
Crossplane v2 automatically creates a default [MRAP]({{<ref "../managed-resources/managed-resource-activation-policies">}}) that activates all managed
resources (`*`). Before installing v2 providers, you can optionally customize
this for better cluster resource efficiency.
Check what managed resources you use:
```shell
# See your managed resource types
kubectl get managed
```
Optionally, replace the default MRAP with a targeted one that activates only
the resources you need:
```shell
# Delete the default catch-all MRAP
kubectl delete mrap default
```
Create a targeted MRAP:
```yaml
apiVersion: apiextensions.crossplane.io/v1alpha1
kind: ManagedResourceActivationPolicy
metadata:
name: my-resources
spec:
activate:
# Legacy cluster-scoped resources (existing v1 resources)
- buckets.s3.aws.upbound.io
- instances.ec2.aws.upbound.io
# Modern namespaced resources (new v2 resources)
- buckets.s3.aws.m.upbound.io
- instances.ec2.aws.m.upbound.io
```
{{<hint "tip">}}
Notice the distinction: `s3.aws.upbound.io` (legacy cluster-scoped) vs
`s3.aws.m.upbound.io` (v2 namespaced). The `.m.` indicates modern
namespaced managed resources.
{{</hint>}}
### 4. Upgrade providers
Upgrade your providers to versions that support both namespaced and
cluster-scoped managed resources:
```shell
# Check current provider versions
kubectl get providers
```
Update your provider manifests to use v2 versions:
```yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: crossplane-contrib-provider-aws-s3
spec:
package: xpkg.crossplane.io/crossplane-contrib/provider-aws-s3:v2.0.0
```
{{<hint "note">}}
Provider v2 releases support both legacy cluster-scoped and new namespaced
managed resources. Your existing cluster-scoped MRs continue working unchanged.
{{</hint>}}
### 5. Start using v2 features
After upgrading, you can begin using Crossplane v2 features:
- **Namespaced managed resources**: Try the [managed resources getting started guide]({{<ref "../get-started/get-started-with-managed-resources">}})
- **Composition functions**: Follow the [composition getting started guide]({{<ref "../get-started/get-started-with-composition">}})
- **Operations**: Explore the [operations getting started guide]({{<ref "../get-started/get-started-with-operations">}})
- **Managed resource definitions**: See the [MRDs guide]({{<ref "./disabling-unused-managed-resources">}})
## Updating compositions for v2
Existing Compositions work with Crossplane v2 with minimal changes. v2 managed
resources are schematically identical to v1 managed resources - they're just
namespaced.
To use v2 namespaced managed resources in compositions:
1. **Update the API group** from `.crossplane.io` to `.m.crossplane.io`
2. **Check the API version** - v2 namespaced providers often reset the API
version to `v1beta1`
For example `provider-aws-s3:v2.0.0` has two `Bucket` MRs:
* `apiVersion: s3.aws.upbound.io/v1beta2` - Legacy, cluster scoped
* `apiVersion: s3.aws.m.upbound.io/v1beta1` - Namespaced
The `spec.forProvider` and `status.atProvider` fields are schematically
identical.
{{<hint "tip">}}
Use `kubectl get mrds` to see available MR API versions.
{{</hint>}}
{{<hint "note">}}
Not all providers use `.crossplane.io` domains. For example, `provider-aws-s3`
uses `.upbound.io` domains for historical reasons. The general pattern for
namespaced resources is adding `.m` to the existing domain: `<domain>` becomes
`m.<domain>` (like `upbound.io``m.upbound.io` or `crossplane.io`
`m.crossplane.io`).
{{</hint>}}
**Before (v1 cluster-scoped)**:
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: my-app
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XBucket
mode: Pipeline
pipeline:
- step: create-bucket
functionRef:
name: crossplane-contrib-function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
name: {{ .observed.composite.resource.metadata.name }}
spec:
forProvider:
region: us-east-2
```
**After (v2 namespaced)**:
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: my-app
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: Bucket
mode: Pipeline
pipeline:
- step: create-bucket
functionRef:
name: crossplane-contrib-function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: s3.aws.m.upbound.io/v1beta1 # Added .m, reset to v1beta1
kind: Bucket
metadata:
name: {{ .observed.composite.resource.metadata.name }}
spec:
forProvider:
region: us-east-2
```
{{<hint "tip">}}
**Namespace handling in compositions**:
- **Namespaced XRs**: Don't specify `metadata.namespace` in templates.
Crossplane ignores template namespaces and uses the XR's namespace.
- **Modern cluster-scoped XRs** (`scope: Cluster`): Can compose resources in any
namespace. Include `metadata.namespace` in templates to specify the target
namespace.
- **Legacy cluster-scoped XRs** (`scope: LegacyCluster`): Can't compose
namespaced resources.
{{</hint>}}
## Legacy resource behavior
Your existing v1 resources continue working in Crossplane v2:
* **Legacy cluster-scoped XRs**: Continue working with claims support
* **Legacy cluster-scoped MRs**: Continue working unchanged
* **Existing Compositions**: Continue working with legacy XRs
These resources use `LegacyCluster` scope internally and maintain full
backward compatibility.
For example, existing v1-style XRDs continue working with claims:
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.example.crossplane.io
spec:
# v1 XRDs default to LegacyCluster scope (shown explicitly)
scope: LegacyCluster
group: example.crossplane.io
names:
kind: XDatabase
plural: xdatabases
claimNames:
kind: Database
plural: databases
# schema definition...
```
Users can create claims that work as before:
```yaml
apiVersion: example.crossplane.io/v1
kind: Database
metadata:
name: my-database
namespace: production
spec:
engine: postgres
size: large
```
## Next steps
After upgrading:
1. **Explore namespaced resources**: Try creating XRs and MRs in namespaces
2. **Build app compositions**: Use v2's ability to compose any Kubernetes resource
3. **Try Operations**: Experiment with operational workflows
4. **Plan migration**: Consider which existing resources to migrate to v2 patterns
Read more about [what's new in v2]({{<ref "../whats-new">}}) and explore the
updated [composition documentation]({{<ref "../composition/compositions">}}).

View File

@ -299,11 +299,9 @@ Run `kubectl get pkg` to look for any packages that aren't fully qualified, then
update or rebuild any Packages to use fully qualified images as needed. update or rebuild any Packages to use fully qualified images as needed.
{{</hint>}} {{</hint>}}
<!-- vale gitlab.FutureTense = NO --> Crossplane v2 supports legacy v1-style XRs and MRs. Most users can upgrade from
Crossplane v2 supports legacy v1-style XRs and MRs. Most users will be able to v1.x to Crossplane v2 without breaking changes.
upgrade from v1.x to Crossplane v2 without breaking changes.
Existing Compositions will require minor updates to work with Crossplane v2 Existing Compositions require minor updates to work with Crossplane v2
style XRs. A migration guide will be available closer to the final release of style XRs and MRs. Follow the [Crossplane v2 upgrade guide]({{<ref "../guides/upgrade-to-crossplane-v2">}})
Crossplane v2. for step-by-step migration instructions.
<!-- vale gitlab.FutureTense = YES -->

View File

@ -0,0 +1,387 @@
---
title: Upgrade to Crossplane v2
weight: 410
description: "Upgrade from Crossplane v1 to v2"
---
Crossplane v2 introduces significant improvements while maintaining backward
compatibility with most v1 configurations. This guide helps you upgrade from
Crossplane v1.x to v2.
Learn about [new features in Crossplane v2]({{<ref "../whats-new">}}) including
namespaced resources, the ability to compose any Kubernetes resource, and new
operational workflows.
{{<hint "important">}}
Only upgrade to Crossplane v2 from Crossplane v1.20, the final v1.x release.
If you're running an earlier version, upgrade to v1.20 first.
{{</hint>}}
{{<hint "note">}}
There's no automated tooling yet to migrate existing v1 cluster-scoped XRs and
MRs to v2 namespaced style. You can upgrade to Crossplane v2 and
start using the new namespaced features right away - your existing v1
resources continue working unchanged. See
[crossplane/crossplane#6726](https://github.com/crossplane/crossplane/issues/6726)
for migration tooling progress.
{{</hint>}}
## Prerequisites
Before upgrading, ensure:
* You're running Crossplane v1.20
* You're not using deprecated features (see [removed features](#removed-features))
* All packages use fully qualified image names
* [Helm](https://helm.sh/docs/intro/install/) version v3.2.0 or later
## Removed features
Crossplane v2 removes these deprecated features:
* [Native patch and transform composition](#native-patch-and-transform-composition)
* [ControllerConfig type](#controllerconfig-type)
* [External secret stores](#external-secret-stores)
* [Default registry flag](#default-registry-flag)
### Native patch and transform composition
**Deprecated in**: v1.17
**Replaced by**: [Composition functions]({{<ref "../composition/compositions">}})
If you're using `spec.mode: Resources` in your Compositions, migrate to
composition functions before upgrading.
**Migration help**: use the Crossplane v1.20 CLI to automatically convert your
Compositions:
```shell
# Convert patch and transform to function pipelines
crossplane beta convert pipeline-composition old-composition.yaml -o new-composition.yaml
```
<!-- vale Google.Headings = NO -->
### ControllerConfig type
<!-- vale Google.Headings = YES -->
**Deprecated in**: v1.11
**Replaced by**: [DeploymentRuntimeConfig]({{<ref "../packages/providers#runtime-configuration">}})
Update any ControllerConfig resources to use DeploymentRuntimeConfig instead.
**Migration help**: use the Crossplane v1.20 CLI to automatically convert your
ControllerConfigs:
```shell
# Convert ControllerConfig to DeploymentRuntimeConfig
crossplane beta convert deployment-runtime controller-config.yaml -o deployment-runtime-config.yaml
```
### External secret stores
**Status**: alpha feature, unmaintained
If you're using external secret stores, migrate to native Kubernetes secrets
or [External Secrets Operator](https://external-secrets.io/latest/) before upgrading.
### Default registry flag
**Removed**: `--registry` flag for default package registry
All packages must now use fully qualified names including the registry
host name. Check your packages with:
```shell
kubectl get pkg -o wide
```
Update any packages without registry host names before upgrading. For example:
- ❌ `crossplane-contrib/provider-aws-s3:v1.23.0`
- ✅ `xpkg.crossplane.io/crossplane-contrib/provider-aws-s3:v1.23.0`
## Who can upgrade
You can upgrade to Crossplane v2 if you meet these criteria:
* ✅ Running Crossplane v1.20
* ✅ Not using native patch and transform composition
* ✅ Not using ControllerConfig resources
* ✅ Not using external secret stores
* ✅ All packages use fully qualified image names
If you're using any removed features, migrate away from them first.
## Upgrade approach
The recommended upgrade approach:
1. [Prepare for upgrade](#1-prepare-for-upgrade)
2. [Upgrade Crossplane core](#2-upgrade-crossplane-core)
3. [Configure managed resource activation policies](#3-configure-managed-resource-activation-policies)
4. [Upgrade providers](#4-upgrade-providers)
5. [Start using v2 features](#5-start-using-v2-features)
### 1. Prepare for upgrade
Review your cluster for [removed features](#removed-features) and address any
that you're using. Each removed feature section includes commands to inspect
your cluster and migration tools to help convert resources.
### 2. Upgrade Crossplane core
Add the Crossplane Helm repository:
```shell
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
```
Upgrade to Crossplane v2:
```shell
helm upgrade crossplane \
--namespace crossplane-system \
crossplane-stable/crossplane
```
Verify the upgrade:
```shell
kubectl get pods -n crossplane-system
```
### 3. Configure managed resource activation policies
Crossplane v2 automatically creates a default [MRAP]({{<ref "../managed-resources/managed-resource-activation-policies">}}) that activates all managed
resources (`*`). Before installing v2 providers, you can optionally customize
this for better cluster resource efficiency.
Check what managed resources you use:
```shell
# See your managed resource types
kubectl get managed
```
Optionally, replace the default MRAP with a targeted one that activates only
the resources you need:
```shell
# Delete the default catch-all MRAP
kubectl delete mrap default
```
Create a targeted MRAP:
```yaml
apiVersion: apiextensions.crossplane.io/v1alpha1
kind: ManagedResourceActivationPolicy
metadata:
name: my-resources
spec:
activate:
# Legacy cluster-scoped resources (existing v1 resources)
- buckets.s3.aws.upbound.io
- instances.ec2.aws.upbound.io
# Modern namespaced resources (new v2 resources)
- buckets.s3.aws.m.upbound.io
- instances.ec2.aws.m.upbound.io
```
{{<hint "tip">}}
Notice the distinction: `s3.aws.upbound.io` (legacy cluster-scoped) vs
`s3.aws.m.upbound.io` (v2 namespaced). The `.m.` indicates modern
namespaced managed resources.
{{</hint>}}
### 4. Upgrade providers
Upgrade your providers to versions that support both namespaced and
cluster-scoped managed resources:
```shell
# Check current provider versions
kubectl get providers
```
Update your provider manifests to use v2 versions:
```yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: crossplane-contrib-provider-aws-s3
spec:
package: xpkg.crossplane.io/crossplane-contrib/provider-aws-s3:v2.0.0
```
{{<hint "note">}}
Provider v2 releases support both legacy cluster-scoped and new namespaced
managed resources. Your existing cluster-scoped MRs continue working unchanged.
{{</hint>}}
### 5. Start using v2 features
After upgrading, you can begin using Crossplane v2 features:
- **Namespaced managed resources**: Try the [managed resources getting started guide]({{<ref "../get-started/get-started-with-managed-resources">}})
- **Composition functions**: Follow the [composition getting started guide]({{<ref "../get-started/get-started-with-composition">}})
- **Operations**: Explore the [operations getting started guide]({{<ref "../get-started/get-started-with-operations">}})
- **Managed resource definitions**: See the [MRDs guide]({{<ref "./disabling-unused-managed-resources">}})
## Updating compositions for v2
Existing Compositions work with Crossplane v2 with minimal changes. v2 managed
resources are schematically identical to v1 managed resources - they're just
namespaced.
To use v2 namespaced managed resources in compositions:
1. **Update the API group** from `.crossplane.io` to `.m.crossplane.io`
2. **Check the API version** - v2 namespaced providers often reset the API
version to `v1beta1`
For example `provider-aws-s3:v2.0.0` has two `Bucket` MRs:
* `apiVersion: s3.aws.upbound.io/v1beta2` - Legacy, cluster scoped
* `apiVersion: s3.aws.m.upbound.io/v1beta1` - Namespaced
The `spec.forProvider` and `status.atProvider` fields are schematically
identical.
{{<hint "tip">}}
Use `kubectl get mrds` to see available MR API versions.
{{</hint>}}
{{<hint "note">}}
Not all providers use `.crossplane.io` domains. For example, `provider-aws-s3`
uses `.upbound.io` domains for historical reasons. The general pattern for
namespaced resources is adding `.m` to the existing domain: `<domain>` becomes
`m.<domain>` (like `upbound.io``m.upbound.io` or `crossplane.io`
`m.crossplane.io`).
{{</hint>}}
**Before (v1 cluster-scoped)**:
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: my-app
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XBucket
mode: Pipeline
pipeline:
- step: create-bucket
functionRef:
name: crossplane-contrib-function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
name: {{ .observed.composite.resource.metadata.name }}
spec:
forProvider:
region: us-east-2
```
**After (v2 namespaced)**:
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: my-app
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: Bucket
mode: Pipeline
pipeline:
- step: create-bucket
functionRef:
name: crossplane-contrib-function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: s3.aws.m.upbound.io/v1beta1 # Added .m, reset to v1beta1
kind: Bucket
metadata:
name: {{ .observed.composite.resource.metadata.name }}
spec:
forProvider:
region: us-east-2
```
{{<hint "tip">}}
**Namespace handling in compositions**:
- **Namespaced XRs**: Don't specify `metadata.namespace` in templates.
Crossplane ignores template namespaces and uses the XR's namespace.
- **Modern cluster-scoped XRs** (`scope: Cluster`): Can compose resources in any
namespace. Include `metadata.namespace` in templates to specify the target
namespace.
- **Legacy cluster-scoped XRs** (`scope: LegacyCluster`): Can't compose
namespaced resources.
{{</hint>}}
## Legacy resource behavior
Your existing v1 resources continue working in Crossplane v2:
* **Legacy cluster-scoped XRs**: Continue working with claims support
* **Legacy cluster-scoped MRs**: Continue working unchanged
* **Existing Compositions**: Continue working with legacy XRs
These resources use `LegacyCluster` scope internally and maintain full
backward compatibility.
For example, existing v1-style XRDs continue working with claims:
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.example.crossplane.io
spec:
# v1 XRDs default to LegacyCluster scope (shown explicitly)
scope: LegacyCluster
group: example.crossplane.io
names:
kind: XDatabase
plural: xdatabases
claimNames:
kind: Database
plural: databases
# schema definition...
```
Users can create claims that work as before:
```yaml
apiVersion: example.crossplane.io/v1
kind: Database
metadata:
name: my-database
namespace: production
spec:
engine: postgres
size: large
```
## Next steps
After upgrading:
1. **Explore namespaced resources**: Try creating XRs and MRs in namespaces
2. **Build app compositions**: Use v2's ability to compose any Kubernetes resource
3. **Try Operations**: Experiment with operational workflows
4. **Plan migration**: Consider which existing resources to migrate to v2 patterns
Read more about [what's new in v2]({{<ref "../whats-new">}}) and explore the
updated [composition documentation]({{<ref "../composition/compositions">}}).

View File

@ -299,11 +299,9 @@ Run `kubectl get pkg` to look for any packages that aren't fully qualified, then
update or rebuild any Packages to use fully qualified images as needed. update or rebuild any Packages to use fully qualified images as needed.
{{</hint>}} {{</hint>}}
<!-- vale gitlab.FutureTense = NO --> Crossplane v2 supports legacy v1-style XRs and MRs. Most users can upgrade from
Crossplane v2 supports legacy v1-style XRs and MRs. Most users will be able to v1.x to Crossplane v2 without breaking changes.
upgrade from v1.x to Crossplane v2 without breaking changes.
Existing Compositions will require minor updates to work with Crossplane v2 Existing Compositions require minor updates to work with Crossplane v2
style XRs. A migration guide will be available closer to the final release of style XRs and MRs. Follow the [Crossplane v2 upgrade guide]({{<ref "../guides/upgrade-to-crossplane-v2">}})
Crossplane v2. for step-by-step migration instructions.
<!-- vale gitlab.FutureTense = YES -->