Crossplane logo
Crossplane logo
  • Why Control Planes?
  • Documentation
  • Community
  • Blog
  • Crossplane GitHub
  • Crossplane Slack
Crossplane Documentation - v
Welcome
What's Crossplane?
What's New in v2?
Get Started
Install Crossplane
Get Started With Composition
Get Started With Managed Resources
Get Started With Operations
Composition
Composite Resources
Composite Resource Definitions
Compositions
Composition Revisions
Environment Configs
Managed Resources
Managed Resources
Managed Resource Definitions
Managed Resource Activation Policies
Usages
Operations
Operations
Cron Operations
Watch Operations
Packages
Providers
Functions
Configurations
Image Configs
Guides
Crossplane Pods
Metrics
Function Patch and Transform
Releasing Crossplane Extensions
Write a Composition Function in Go
Write a Composition Function in Python
Disabling Unused Managed Resources
Implementing safe-start in Providers
Troubleshoot Crossplane
Upgrade Crossplane
Upgrade to Crossplane v2
Uninstall Crossplane
CLI Reference
Command Reference
API Reference
Learn More
Release Cycle
Feature Lifecycle
Contributing Guide
Crossplane Roadmap
v2.0
Latest
master v2.0-preview v2.0
Latest
v1.20 v1.19

Disabling Unused Managed Resources

This is an alpha feature. Crossplane may change or drop this feature at any time.

This feature was introduced in v2.

For more information read the Crossplane feature lifecycle.

On this page
  • Before you begin
  • The problem: Resource overhead
  • Step 1: Disable automatic activation
    • Option A: Helm installation
    • Option B: Existing installation
  • Step 2: Install your provider
  • Step 3: Verify Crossplane created MRDs
  • Step 4: Create an activation policy
  • Step 5: Verify selective activation
  • Step 6: Measure the impact
  • Next steps
Report a problem
View page source
Important
This guide uses managed resource definitions and managed resource activation policies, which Crossplane v2.0+ enables by default. To disable this behavior, set --enable-custom-to-managed-resource-conversion=false when installing Crossplane.

Large Crossplane providers can install 100+ managed resource CRDs, consuming significant cluster resources even when you only need one or two resource types. This guide shows how to use ManagedResourceDefinitions and ManagedResourceActivationPolicies to install only the provider resources you actually need.

Before you begin

This guide requires:

  • Crossplane v2.0+ installed in your cluster
  • A provider with safe-start capability (this guide uses provider-aws-ec2:v2.0.0)
  • Basic familiarity with Kubernetes and Crossplane concepts
Important
ManagedResourceDefinitions and ManagedResourceActivationPolicies are alpha features in Crossplane v2.0+.

The problem: Resource overhead

Installing a large cloud provider in Crossplane creates hundreds of CRDs:

1# Before selective activation - provider-aws-ec2 installs ~200 CRDs 2kubectl get crds | grep aws.crossplane.io | wc -l 3# Output: 200 4 5# Each CRD consumes ~3 MiB of API server memory 6# 200 CRDs × 3 MiB = 600 MiB of memory usage 

Most users only need a small subset of these resources. Selective activation lets you install just what you need.

Step 1: Disable automatic activation

By default, the Crossplane Helm chart creates an activation policy that enables all provider resources. To use selective activation, disable this default behavior.

Option A: Helm installation

1helm install crossplane crossplane-stable/crossplane \ 2  --namespace crossplane-system \ 3  --create-namespace \ 4  --set provider.defaultActivations={} 

Option B: Existing installation

Delete the default activation policy:

1kubectl delete managedresourceactivationpolicy default 

Step 2: Install your provider

Install your provider as normal. Crossplane automatically converts the provider’s CRDs to ManagedResourceDefinitions:

1apiVersion: pkg.crossplane.io/v1 2kind: Provider 3metadata: 4  name: provider-aws-ec2 5spec: 6  package: xpkg.crossplane.io/provider-aws-ec2:v2.0.0 

Save this as provider.yaml and apply it:

1kubectl apply -f provider.yaml 2 3# Wait for provider to be ready 4kubectl wait --for=condition=Healthy provider/provider-aws-ec2 --timeout=5m 

Step 3: Verify Crossplane created MRDs

After the provider installs, check ManagedResourceDefinitions that Crossplane created in inactive state:

1# List ManagedResourceDefinitions 2kubectl get managedresourcedefinitions 3 4# Check their states (should be "Inactive") 5kubectl get mrds -o jsonpath='{.items[*].spec.state}' \ 6  | tr ' ' '\n' | sort | uniq -c 7# 200 Inactive 

Notice that Crossplane didn’t create any CRDs yet:

1kubectl get crds | grep ec2.aws.m.crossplane.io 2# No output - CRDs don't exist until MRDs are activated 

Step 4: Create an activation policy

Create a ManagedResourceActivationPolicy to selectively activate only the resources you need:

1apiVersion: apiextensions.crossplane.io/v1alpha1 2kind: ManagedResourceActivationPolicy 3metadata: 4  name: my-app-resources 5spec: 6  activate: 7  - instances.ec2.aws.m.crossplane.io        # EC2 instances for compute 8  - securitygroups.ec2.aws.m.crossplane.io   # Security groups for networking 9  - vpcs.ec2.aws.m.crossplane.io             # VPCs for isolation 

Save this as activation-policy.yaml and apply it:

1kubectl apply -f activation-policy.yaml 

Step 5: Verify selective activation

Check that Crossplane activated only the specified resources:

 1# Check MRD states - only some should be Active now  2kubectl get mrds \  3  -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.state}{"\n"}{end}' \  4  | grep Active  5# instances.ec2.aws.m.crossplane.io: Active  6# securitygroups.ec2.aws.m.crossplane.io: Active  7# vpcs.ec2.aws.m.crossplane.io: Active  8  9# Verify Crossplane created corresponding CRDs 10kubectl get crds | grep ec2.aws.m.crossplane.io 11# instances.ec2.aws.m.crossplane.io 12# securitygroups.ec2.aws.m.crossplane.io 13# vpcs.ec2.aws.m.crossplane.io 14 15# Count CRDs from EC2 provider - should match activated MRDs 16kubectl get crds | grep ec2.aws.m.crossplane.io | wc -l 17# 3 (only the activated resources) 

Step 6: Measure the impact

Check the significant reduction in resource overhead:

 1# Count CRDs from EC2 provider - should be much lower than 200  2kubectl get crds | grep aws.crossplane.io | wc -l  3# 3 CRDs (99% reduction from 200)  4  5# Calculate memory savings  6echo "197 CRDs saved × 3 MiB = 591 MiB saved (99% reduction)"  7  8# Verify inactive MRDs still exist but consume minimal resources  9kubectl get mrds \ 10  -o jsonpath='{.items[?(@.spec.state=="Inactive")]..metadata.name}' | wc -w 11# 197 inactive MRDs (~20 MiB total overhead vs 600 MiB for active CRDs) 12 13# Check total MRDs (active + inactive) 14kubectl get mrds | wc -l 15# 200 total MRDs (3 active, 197 inactive) 

The selective activation provides massive resource savings while maintaining full capability for the resources you actually use.

Next steps

  • Learn more about ManagedResourceDefinitions for detailed concepts and troubleshooting
  • Explore ManagedResourceActivationPolicies for advanced activation strategies and best practices
  • Check the API reference for complete schema documentation
Crossplane logo
Twitter
Youtube
Podcast
Forum

© Crossplane Authors 2025. Documentation distributed under CC-BY-4.0.

© 2025 The Linux Foundation. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page.

cncfLogo

We are a Cloud Native Computing Foundation incubating project.