-
Notifications
You must be signed in to change notification settings - Fork 146
Guide for updating v1 -> v2 #976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+784
−14
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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">}}). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this possibly result in the external resource being deleted? i.e. we're changing the composed resource to a new type, so will any XR that uses this composition basically stop including the old cluster scoped one in their desired resources, resulting in it being deleted? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 asking myself the exact same question :)