content/v2.0/managed-resources/managed-resource-definitions.md
{{<hint "important">}}
Crossplane v2.0+ enables managed resource definitions by default. This
automatically converts provider CRDs to MRDs during installation. To disable
this
behavior, set --enable-custom-to-managed-resource-conversion=false when
installing Crossplane.
{{</hint>}}
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.
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:
kubectl get managed must query
all custom resource endpointsMRDs address this by allowing providers to ship resource definitions that only become active CRDs when explicitly needed.
<!-- vale Google.Headings = NO --> <!-- vale Microsoft.HeadingAcronyms = NO -->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 (Active or
Inactive)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.
apiVersion: apiextensions.crossplane.io/v1alpha1
kind: ManagedResourceDefinition
metadata:
name: buckets.s3.aws.m.crossplane.io
spec:
group: s3.aws.m.crossplane.io
names:
kind: Bucket
plural: buckets
scope: Cluster
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
forProvider:
type: object
properties:
region:
type: string
versioning:
type: boolean
connectionDetails:
- name: bucket-name
description: The name of the created S3 bucket
- name: region
description: The AWS region where the bucket was created
state: Inactive # Default state - no CRD created yet
Inactive to Active but not
backWhen state: Inactive (the default):
spec:
state: Inactive # Default for all MRDs
When state: Active:
spec:
state: Active # CRD will be created
{{<hint "important">}}
MRD state transitions are one-way only. Once an MRD becomes Active, it can't
return to Inactive. This prevents accidental deletion of CRDs that may have
existing resources.
{{</hint>}}
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.
spec:
connectionDetails:
- name: endpoint
description: The RDS instance endpoint for database connections
- name: port
description: The port number for database connections
- name: username
description: The master username for database access
- name: password
description: The auto-generated master password
{{<hint "note">}}
<!-- vale write-good.Passive = NO --> <!-- vale gitlab.CurrentStatus = NO --> <!-- vale write-good.Weasel = NO -->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.
{{</hint>}}
<!-- vale Google.Headings = NO --> <!-- vale Microsoft.HeadingAcronyms = NO -->List all MRDs in your cluster:
kubectl get managedresourcedefinitions
View MRD details:
kubectl describe mrd buckets.s3.aws.m.crossplane.io
MRDs provide status information about their lifecycle:
status:
conditions:
- type: Established
status: "False"
reason: InactiveManagedResource
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 issuesYou can manually activate an MRD by changing its state:
kubectl patch mrd buckets.s3.aws.m.crossplane.io --type='merge' \
-p='{"spec":{"state":"Active"}}'
The recommended approach is to use [ManagedResourceActivationPolicies]({{<ref "managed-resource-activation-policies">}}) for systematic activation.
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:
safe-start capabilitystate: Inactive by default# Provider package metadata
apiVersion: meta.pkg.crossplane.io/v1
kind: Provider
spec:
capabilities:
- safe-start
{{<hint "tip">}}
Crossplane uses fuzzy matching for capabilities, so safe-start,
safe_start, safestart, and SafeStart all match the safe-start
capability.
{{</hint>}}
safe-start capabilitystate: Active by default (legacy behavior)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]({{<ref "managed-resource-activation-policies">}}) or manually patch the state
<!-- vale Google.Colons = YES --># Check MRD state
kubectl get mrd <name> -o jsonpath='{.spec.state}'
# Activate if needed
kubectl patch mrd <name> --type='merge' -p='{"spec":{"state":"Active"}}'
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
<!-- vale Google.Colons = YES -->kubectl describe mrd <name>
Other status conditions for troubleshooting:
Established: False, Reason: BlockedManagedResourceActivationPolicy:
Blocked by activation policy issuesEstablished: False, Reason: TerminatingManagedResource: Crossplane is
deleting the MRDCommon events you might see:
Normal CreateCustomResourceDefinition - CRD successfully createdNormal UpdateCustomResourceDefinition - CRD successfully updatedWarning CreateCustomResourceDefinition - CRD creation failedWarning UpdateCustomResourceDefinition - CRD update failedWarning Reconcile - General reconciliation errorsCommon issues:
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
<!-- vale Google.Colons = YES --># Check if provider supports late activation
kubectl get providerrevision <provider-revision-name> \
-o jsonpath='{.status.capabilities}'
Look for the safe-start capability.