Managed Resource Definitions
This feature was introduced in v2.
For more information read the Crossplane feature lifecycle.
--enable-custom-to-managed-resource-conversion=false when
installing Crossplane.A ManagedResourceDefinition (MRD) is a lightweight abstraction over
Kubernetes CustomResourceDefinitions (CRDs) that enables selective activation of
managed resources. MRDs solve the problem of providers installing hundreds of
CRDs when you only need one or two, reducing API server overhead and improving
cluster performance.
The CRD scaling problem
Large Crossplane providers can install 100+ managed resource CRDs. Each CRD consumes about 3 MiB of API server memory and creates API endpoints that affect cluster performance:
- Memory pressure: Large providers can consume 300+ MiB of API server memory
- Slower kubectl operations: Commands like
kubectl get managedmust query all custom resource endpoints - Increased API server load: More CRDs mean more API endpoints to serve
- Unnecessary resource overhead: Most users only need a subset of provider resources
MRDs address this by allowing providers to ship resource definitions that only become active CRDs when explicitly needed.
How MRDs work
An MRD contains the same schema as a CRD but adds two key fields:
connectionDetails: Documents what connection secrets the resource providesstate: Controls whether the underlying CRD exists (ActiveorInactive)
When an MRD’s state is Inactive, no CRD exists in the cluster. When
activated, Crossplane creates the corresponding CRD and the provider can start
managing instances of that resource.
1apiVersion: apiextensions.crossplane.io/v1alpha1
2kind: ManagedResourceDefinition
3metadata:
4 name: buckets.s3.aws.m.crossplane.io
5spec:
6 group: s3.aws.m.crossplane.io
7 names:
8 kind: Bucket
9 plural: buckets
10 scope: Cluster
11 versions:
12 - name: v1alpha1
13 served: true
14 storage: true
15 schema:
16 openAPIV3Schema:
17 type: object
18 properties:
19 spec:
20 type: object
21 properties:
22 forProvider:
23 type: object
24 properties:
25 region:
26 type: string
27 versioning:
28 type: boolean
29 connectionDetails:
30 - name: bucket-name
31 description: The name of the created S3 bucket
32 - name: region
33 description: The AWS region where the bucket was created
34 state: Inactive # Default state - no CRD created yet
Key characteristics
- Selective activation: Only create CRDs for resources you actually need
- Performance benefits: Inactive MRDs consume minimal cluster resources
- Connection details documentation: Schema for documenting available connection secrets
- One-way state transition: MRDs can go from
InactivetoActivebut not back
MRD states
Inactive state
When state: Inactive (the default):
- No CRD exists in the cluster
- No API endpoints exist
- The provider doesn’t start a controller for this resource
- Minimal memory and CPU overhead
Active state
When state: Active:
- Crossplane creates the corresponding CRD
- API endpoints become available for the resource
- The provider starts a controller to manage instances
- Full capability like traditional managed resources
Active, it can’t
return to Inactive. This prevents accidental deletion of CRDs that may have
existing resources.Connection details documentation
MRDs can document what connection details a managed resource provides. This helps users understand what data is available in connection secrets without having to create test resources.
1spec:
2 connectionDetails:
3 - name: endpoint
4 description: The RDS instance endpoint for database connections
5 - name: port
6 description: The port number for database connections
7 - name: username
8 description: The master username for database access
9 - name: password
10 description: The auto-generated master password
Connection details are currently a schema-only feature. Most providers
don’t yet populate the connectionDetails field in their MRDs, but the structure
is available for future implementation.
Working with MRDs
Viewing MRDs
List all MRDs in your cluster:
1kubectl get managedresourcedefinitions
View MRD details:
1kubectl describe mrd buckets.s3.aws.m.crossplane.io
Checking MRD status
MRDs provide status information about their lifecycle:
1status:
2 conditions:
3 - type: Established
4 status: "False"
5 reason: InactiveManagedResource
6 message: "ManagedResourceDefinition is inactive"
Status conditions:
Established: False, Reason: InactiveManagedResource: MRD is inactive, no CRD createdEstablished: Unknown, Reason: PendingManagedResource: Crossplane is creating the CRDEstablished: True, Reason: EstablishedManagedResource: CRD exists and is readyHealthy: True, Reason: Running: MRD controller operatingHealthy: Unknown, Reason: EncounteredErrors: MRD controller experiencing issues
Manually activating MRDs
You can manually activate an MRD by changing its state:
1kubectl patch mrd buckets.s3.aws.m.crossplane.io --type='merge' \
2 -p='{"spec":{"state":"Active"}}'
The recommended approach is to use ManagedResourceActivationPolicies for systematic activation.
How providers work with MRDs
Crossplane v2.0+ automatically converts all provider CRDs to MRDs during
package installation, regardless of the provider’s age or original format. The
provider’s safe-start capability determines the default MRD state:
Providers with safe-start capability
- MRDs start with
state: Inactiveby default - Support selective activation via ManagedResourceActivationPolicies
- Reduced resource overhead for unused resources
- Provider can start without all CRDs being active
1# Provider package metadata
2apiVersion: meta.pkg.crossplane.io/v1
3kind: Provider
4spec:
5 capabilities:
6 - safe-start
safe-start,
safe_start, safestart, and SafeStart all match the safe-start
capability.Providers without safe-start capability
- MRDs start with
state: Activeby default (legacy behavior) - All CRDs become available for backward compatibility
- Full resource overhead like traditional providers
Troubleshooting MRDs
MRD exists but no CRD appears
Symptoms: MRD is present but kubectl get <resource> shows “no
resources found”
Cause: MRD is in Inactive state
Solution: Activate the MRD using an ManagedResourceActivationPolicy or manually patch the state
1# Check MRD state
2kubectl get mrd <name> -o jsonpath='{.spec.state}'
3
4# Activate if needed
5kubectl patch mrd <name> --type='merge' -p='{"spec":{"state":"Active"}}'
MRD activation fails
Symptoms: MRD state is Active but Established condition remains False
Cause: CRD creation failed due to schema issues or conflicts
Solution: Check MRD events and status for error details
1kubectl describe mrd <name>
Other status conditions for troubleshooting:
Established: False, Reason: BlockedManagedResourceActivationPolicy: Blocked by activation policy issuesEstablished: False, Reason: TerminatingManagedResource: Crossplane is deleting the MRD
Common events you might see:
Normal CreateCustomResourceDefinition- CRD successfully createdNormal UpdateCustomResourceDefinition- CRD successfully updatedWarning CreateCustomResourceDefinition- CRD creation failedWarning UpdateCustomResourceDefinition- CRD update failedWarning Reconcile- General reconciliation errors
Common issues:
- Malformed OpenAPI schema in the MRD
- CRD name conflicts with existing resources
- Insufficient RBAC permissions for Crossplane
Provider doesn’t support activation
Symptoms: Provider starts all controllers regardless of MRD states
Cause: Provider doesn’t implement late activation support
Solution: Check provider capabilities and use a compatible provider version
1# Check if provider supports late activation
2kubectl get providerrevision <provider-revision-name> \
3 -o jsonpath='{.status.capabilities}'
Look for the safe-start capability.
Next steps
- Learn about ManagedResourceActivationPolicies for systematic resource activation
- See the disabling unused managed resources guide for practical implementation
- Check the API reference for complete MRD schema documentation