Q: Crossplane releases a major breaking upgrade for provider-aws (v0.40 -> v1.0.0 with Upjet architecture), deprecating older API groups (`rds.aws.crossplane.io/v1alpha1` -> `rds.aws.upjet.crossplane.io/v1beta1`). How do you execute this provider upgrade across production clusters without deleting active cloud databases?
Safely executing major version upgrades of Crossplane cloud providers without causing controller reconciliation downtime or resource deletion.
Want to master this scenario in a live sandbox? KodeKloud's CKA & CKAD Hands-On Certification Track covers this exact problem with hands-on terminal drills.
🛠️ Production Runbook & Step-by-Step Resolution
Pause Reconciliation on All Managed Resources
Before upgrading the provider, apply the `crossplane.io/paused: true` annotation across all managed resources to prevent active reconciliation during controller swap.
kubectl annotate instances.rds.aws.crossplane.io --all crossplane.io/paused=true
Deploy New Upjet Provider Alongside Legacy Provider
Install the new Upjet provider package alongside the old provider. Migrate Composite Resources (Compositions) to generate the new API group (`upjet.crossplane.io`), ensuring the `crossplane.io/external-name` matches the existing AWS resource identifier exactly.
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws-rds-upjet
spec:
package: xpkg.upbound.io/upbound/provider-aws-rds:v1.2.0
Migrate State and Remove Legacy Provider
Remove the pause annotation on the new resource, confirm that the Upjet controller detects the existing AWS resource via its external name and enters `Ready: True`, then cleanly decommission the legacy provider package.
- Pause Crossplane resource reconciliation using crossplane.io/paused annotations prior to provider upgrades.
- Ensure the new provider compositions match the exact existing external-name to adopt cloud infrastructure.
- Enforce deletionPolicy: Orphan across all resources to protect live production cloud assets.