mirror of https://github.com/crossplane/docs.git
commit
f1a6d852f4
|
|
@ -0,0 +1,214 @@
|
||||||
|
---
|
||||||
|
title: Disabling Unused Managed Resources
|
||||||
|
weight: 85
|
||||||
|
state: alpha
|
||||||
|
alphaVersion: 2.0
|
||||||
|
description: Reduce CRD overhead by disabling unused managed resources
|
||||||
|
---
|
||||||
|
|
||||||
|
{{<hint "important">}}
|
||||||
|
This guide uses
|
||||||
|
[managed resource definitions]({{<ref "../managed-resources/managed-resource-definitions">}})
|
||||||
|
and
|
||||||
|
[managed resource activation policies]({{<ref "../managed-resources/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.
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
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]({{<ref "../managed-resources/managed-resource-definitions">}})
|
||||||
|
and
|
||||||
|
[ManagedResourceActivationPolicies]({{<ref "../managed-resources/managed-resource-activation-policies">}})
|
||||||
|
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
|
||||||
|
|
||||||
|
{{<hint "important">}}
|
||||||
|
ManagedResourceDefinitions and ManagedResourceActivationPolicies are alpha
|
||||||
|
features in Crossplane v2.0+.
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
## The problem: Resource overhead
|
||||||
|
|
||||||
|
Installing a large cloud provider in Crossplane creates hundreds of CRDs:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Before selective activation - provider-aws-ec2 installs ~200 CRDs
|
||||||
|
kubectl get crds | grep aws.crossplane.io | wc -l
|
||||||
|
# Output: 200
|
||||||
|
|
||||||
|
# Each CRD consumes ~3 MiB of API server memory
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
### Option A: Helm installation
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
```shell
|
||||||
|
helm install crossplane crossplane-stable/crossplane \
|
||||||
|
--namespace crossplane-system \
|
||||||
|
--create-namespace \
|
||||||
|
--set provider.defaultActivations={}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
### Option B: Existing installation
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
Delete the default activation policy:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl delete managedresourceactivationpolicy default
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2: Install your provider
|
||||||
|
|
||||||
|
Install your provider as normal. Crossplane automatically converts the
|
||||||
|
provider's CRDs to ManagedResourceDefinitions:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: pkg.crossplane.io/v1
|
||||||
|
kind: Provider
|
||||||
|
metadata:
|
||||||
|
name: provider-aws-ec2
|
||||||
|
spec:
|
||||||
|
package: xpkg.crossplane.io/provider-aws-ec2:v2.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Save this as `provider.yaml` and apply it:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f provider.yaml
|
||||||
|
|
||||||
|
# Wait for provider to be ready
|
||||||
|
kubectl wait --for=condition=Healthy provider/provider-aws-ec2 --timeout=5m
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3: Verify Crossplane created MRDs
|
||||||
|
|
||||||
|
<!-- vale Google.WordList = NO -->
|
||||||
|
After the provider installs, check ManagedResourceDefinitions that Crossplane
|
||||||
|
created in inactive state:
|
||||||
|
<!-- vale Google.WordList = YES -->
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# List ManagedResourceDefinitions
|
||||||
|
kubectl get managedresourcedefinitions
|
||||||
|
|
||||||
|
# Check their states (should be "Inactive")
|
||||||
|
kubectl get mrds -o jsonpath='{.items[*].spec.state}' \
|
||||||
|
| tr ' ' '\n' | sort | uniq -c
|
||||||
|
# 200 Inactive
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice that Crossplane didn't create any CRDs yet:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get crds | grep ec2.aws.m.crossplane.io
|
||||||
|
# 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:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: my-app-resources
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- instances.ec2.aws.m.crossplane.io # EC2 instances for compute
|
||||||
|
- securitygroups.ec2.aws.m.crossplane.io # Security groups for networking
|
||||||
|
- vpcs.ec2.aws.m.crossplane.io # VPCs for isolation
|
||||||
|
```
|
||||||
|
|
||||||
|
Save this as `activation-policy.yaml` and apply it:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f activation-policy.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5: Verify selective activation
|
||||||
|
|
||||||
|
<!-- vale Google.WordList = NO -->
|
||||||
|
Check that Crossplane activated only the specified resources:
|
||||||
|
<!-- vale Google.WordList = YES -->
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Check MRD states - only some should be Active now
|
||||||
|
kubectl get mrds \
|
||||||
|
-o jsonpath='{range .items[*]}{.metadata.name}: {.spec.state}{"\n"}{end}' \
|
||||||
|
| grep Active
|
||||||
|
# instances.ec2.aws.m.crossplane.io: Active
|
||||||
|
# securitygroups.ec2.aws.m.crossplane.io: Active
|
||||||
|
# vpcs.ec2.aws.m.crossplane.io: Active
|
||||||
|
|
||||||
|
# Verify Crossplane created corresponding CRDs
|
||||||
|
kubectl get crds | grep ec2.aws.m.crossplane.io
|
||||||
|
# instances.ec2.aws.m.crossplane.io
|
||||||
|
# securitygroups.ec2.aws.m.crossplane.io
|
||||||
|
# vpcs.ec2.aws.m.crossplane.io
|
||||||
|
|
||||||
|
# Count CRDs from EC2 provider - should match activated MRDs
|
||||||
|
kubectl get crds | grep ec2.aws.m.crossplane.io | wc -l
|
||||||
|
# 3 (only the activated resources)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 6: Measure the impact
|
||||||
|
|
||||||
|
Check the significant reduction in resource overhead:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Count CRDs from EC2 provider - should be much lower than 200
|
||||||
|
kubectl get crds | grep aws.crossplane.io | wc -l
|
||||||
|
# 3 CRDs (99% reduction from 200)
|
||||||
|
|
||||||
|
# Calculate memory savings
|
||||||
|
echo "197 CRDs saved × 3 MiB = 591 MiB saved (99% reduction)"
|
||||||
|
|
||||||
|
# Verify inactive MRDs still exist but consume minimal resources
|
||||||
|
kubectl get mrds \
|
||||||
|
-o jsonpath='{.items[?(@.spec.state=="Inactive")]..metadata.name}' | wc -w
|
||||||
|
# 197 inactive MRDs (~20 MiB total overhead vs 600 MiB for active CRDs)
|
||||||
|
|
||||||
|
# Check total MRDs (active + inactive)
|
||||||
|
kubectl get mrds | wc -l
|
||||||
|
# 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]({{<ref "../managed-resources/managed-resource-definitions">}})
|
||||||
|
for detailed concepts and troubleshooting
|
||||||
|
- Explore
|
||||||
|
[ManagedResourceActivationPolicies]({{<ref "../managed-resources/managed-resource-activation-policies">}})
|
||||||
|
for advanced activation strategies and best practices
|
||||||
|
- Check the [API reference]({{<ref "../api">}}) for complete schema
|
||||||
|
documentation
|
||||||
|
|
@ -0,0 +1,247 @@
|
||||||
|
---
|
||||||
|
title: Implementing safe-start in Providers
|
||||||
|
weight: 90
|
||||||
|
state: alpha
|
||||||
|
alphaVersion: 2.0
|
||||||
|
description: Guide for provider developers to add safe-start capability for
|
||||||
|
selective resource activation
|
||||||
|
---
|
||||||
|
|
||||||
|
This guide shows provider developers how to implement safe-start capability in
|
||||||
|
their Crossplane providers. safe-start enables
|
||||||
|
[disabling unused managed resources]({{<ref "disabling-unused-managed-resources">}})
|
||||||
|
through ManagedResourceDefinitions, improving performance and reducing resource
|
||||||
|
overhead.
|
||||||
|
|
||||||
|
{{<hint "important">}}
|
||||||
|
safe-start requires Crossplane v2.0+ and crossplane-runtime v2.0+.
|
||||||
|
Implementing safe-start involves code changes that affect provider startup
|
||||||
|
behavior.
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
## What safe-start provides
|
||||||
|
|
||||||
|
safe-start changes how your provider handles CRD installation:
|
||||||
|
|
||||||
|
**Without safe-start:**
|
||||||
|
- Providers create all managed resource CRDs when installed
|
||||||
|
- Users get all resources even if they only need one or two
|
||||||
|
- Higher memory usage and API server load
|
||||||
|
|
||||||
|
**With safe-start:**
|
||||||
|
- Providers create ManagedResourceDefinitions but CRDs only when activated
|
||||||
|
- Users activate only needed resources through ManagedResourceActivationPolicies
|
||||||
|
- Significant reduction in cluster resource overhead
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before implementing safe-start:
|
||||||
|
|
||||||
|
- Provider built with crossplane-runtime v2.0+
|
||||||
|
- Understanding of
|
||||||
|
[ManagedResourceDefinitions]({{<ref "../managed-resources/managed-resource-definitions">}})
|
||||||
|
- Test environment with Crossplane v2.0+
|
||||||
|
|
||||||
|
## Implementation steps
|
||||||
|
|
||||||
|
### Step 1: Declare safe-start capability
|
||||||
|
|
||||||
|
Add safe-start to your provider package metadata:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# package/crossplane.yaml
|
||||||
|
apiVersion: meta.pkg.crossplane.io/v1
|
||||||
|
kind: Provider
|
||||||
|
metadata:
|
||||||
|
name: provider-example
|
||||||
|
spec:
|
||||||
|
capabilities:
|
||||||
|
- safe-start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Add required imports
|
||||||
|
|
||||||
|
Update your main.go imports (see
|
||||||
|
[crossplane-runtime godoc](https://pkg.go.dev/github.com/crossplane/crossplane-runtime/v2)
|
||||||
|
for full API reference):
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
// existing imports...
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
|
||||||
|
"github.com/crossplane/crossplane-runtime/v2/pkg/controller"
|
||||||
|
"github.com/crossplane/crossplane-runtime/v2/pkg/gate"
|
||||||
|
"github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/customresourcesgate"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Initialize the gate
|
||||||
|
|
||||||
|
Add gate initialization in your main function:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
// existing setup code...
|
||||||
|
|
||||||
|
o := controller.Options{
|
||||||
|
// existing options...
|
||||||
|
Gate: new(gate.Gate[schema.GroupVersionKind]),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add CustomResourceDefinition to scheme for gate controller
|
||||||
|
if err := apiextensionsv1.AddToScheme(mgr.GetScheme()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup controllers
|
||||||
|
if err := yourprovider.Setup(mgr, o); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the CRD gate controller
|
||||||
|
if err := customresourcesgate.Setup(mgr, o); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// start manager...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Use gated controller setup
|
||||||
|
|
||||||
|
Create a gated setup function for each managed resource controller:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// SetupGated registers controller setup with the gate, waiting for the
|
||||||
|
// required CRD
|
||||||
|
func SetupGated(mgr ctrl.Manager, o controller.Options) error {
|
||||||
|
o.Gate.Register(func() {
|
||||||
|
if err := Setup(mgr, o); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}, v1alpha1.MyResourceGroupVersionKind)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup is your existing controller setup function (unchanged)
|
||||||
|
func Setup(mgr ctrl.Manager, o controller.Options) error {
|
||||||
|
// existing controller setup code...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Update controller registration
|
||||||
|
|
||||||
|
Change your controller setup to use the gated versions:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/controller/controller.go
|
||||||
|
func Setup(mgr ctrl.Manager, o controller.Options) error {
|
||||||
|
for _, setup := range []func(ctrl.Manager, controller.Options) error{
|
||||||
|
myresource.SetupGated, // Changed from myresource.Setup
|
||||||
|
// other gated setups...
|
||||||
|
} {
|
||||||
|
if err := setup(mgr, o); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation details
|
||||||
|
|
||||||
|
The safe-start implementation uses a "gate" pattern:
|
||||||
|
|
||||||
|
1. **Gate initialization**: Creates a gate that tracks CRD readiness
|
||||||
|
2. **Controller registration**: Controllers register with the gate, specifying
|
||||||
|
which CRDs they need
|
||||||
|
3. **CRD monitoring**: The `customresourcesgate` controller watches for CRD
|
||||||
|
creation/deletion
|
||||||
|
4. **Delayed startup**: Controllers only start when their required CRDs
|
||||||
|
become active
|
||||||
|
|
||||||
|
## Testing your implementation
|
||||||
|
|
||||||
|
Test safe-start behavior with this basic workflow:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Install Crossplane v2.0+
|
||||||
|
helm install crossplane crossplane-stable/crossplane \
|
||||||
|
--namespace crossplane-system \
|
||||||
|
--set provider.defaultActivations={}
|
||||||
|
|
||||||
|
# Install your provider
|
||||||
|
kubectl apply -f provider.yaml
|
||||||
|
|
||||||
|
# Check that MRDs are created but inactive
|
||||||
|
kubectl get mrds
|
||||||
|
# All should show STATE: Inactive
|
||||||
|
|
||||||
|
# No CRDs should exist yet
|
||||||
|
kubectl get crds | grep yourprovider.m.crossplane.io
|
||||||
|
# Should return no results
|
||||||
|
|
||||||
|
# Create activation policy
|
||||||
|
kubectl apply -f - <<EOF
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-activation
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "myresource.yourprovider.m.crossplane.io"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Verify activation worked
|
||||||
|
kubectl get mrd myresource.yourprovider.m.crossplane.io
|
||||||
|
# Should show STATE: Active
|
||||||
|
|
||||||
|
# CRD should now exist
|
||||||
|
kubectl get crd myresource.yourprovider.m.crossplane.io
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Controllers never start
|
||||||
|
**Cause**: gate waits for CRDs that never become active.
|
||||||
|
|
||||||
|
<!-- vale Google.WordList = NO -->
|
||||||
|
**Solution**: check that Crossplane activated MRDs and created CRDs:
|
||||||
|
<!-- vale Google.WordList = YES -->
|
||||||
|
```shell
|
||||||
|
kubectl get mrds -o wide
|
||||||
|
kubectl describe mrap <activation-policy-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
### CRDs don't appear
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Google.Colons = NO -->
|
||||||
|
**Cause**: MRDs might not activate or activation policy doesn't match.
|
||||||
|
<!-- vale Google.Colons = YES -->
|
||||||
|
|
||||||
|
**Solution**: verify activation policy patterns match MRD names:
|
||||||
|
```shell
|
||||||
|
kubectl get mrds
|
||||||
|
kubectl get mrap -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration considerations
|
||||||
|
|
||||||
|
When adding safe-start to existing providers:
|
||||||
|
|
||||||
|
- **Existing installations**: Continue working as expected (no CRD changes)
|
||||||
|
- **New installations**: Start with inactive MRDs, require activation policies
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
- Test your safe-start implementation with different activation patterns
|
||||||
|
- Update provider documentation to explain activation requirements
|
||||||
|
- Consider the user experience for providers that now require activation
|
||||||
|
policies
|
||||||
|
|
||||||
|
Learn more about the user experience in
|
||||||
|
[disabling unused managed resources]({{<ref "disabling-unused-managed-resources">}}).
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Managed Resources
|
title: Managed Resources
|
||||||
weight: 52
|
weight: 52
|
||||||
description: Understand Crossplane's core components
|
description: Understand Crossplane's managed resources and selective activation
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,472 @@
|
||||||
|
---
|
||||||
|
title: Managed Resource Activation Policies
|
||||||
|
weight: 20
|
||||||
|
state: alpha
|
||||||
|
alphaVersion: 2.0
|
||||||
|
description: ManagedResourceActivationPolicies control which
|
||||||
|
ManagedResourceDefinitions activate for selective provider resource
|
||||||
|
installation
|
||||||
|
---
|
||||||
|
|
||||||
|
{{<hint "important">}}
|
||||||
|
Managed resource activation policies work with
|
||||||
|
[managed resource definitions]({{<ref "managed-resource-definitions">}}),
|
||||||
|
which Crossplane v2.0+ enables by default. To disable this behavior, set
|
||||||
|
`--enable-custom-to-managed-resource-conversion=false` when installing
|
||||||
|
Crossplane.
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
A `ManagedResourceActivationPolicy` (MRAP) controls which
|
||||||
|
[ManagedResourceDefinitions]({{<ref "managed-resource-definitions">}})
|
||||||
|
become active in your cluster. MRAPs enable selective installation of provider
|
||||||
|
resources, allowing you to activate only the 10 managed resources you need
|
||||||
|
instead of the 100+ that a provider ships.
|
||||||
|
|
||||||
|
## The selective activation problem
|
||||||
|
|
||||||
|
Modern Crossplane providers can ship dozens or hundreds of managed resources,
|
||||||
|
but most users only need a small subset. Before MRAPs, you got "all or
|
||||||
|
nothing" - installing a provider meant getting every managed resource it
|
||||||
|
supported, consuming unnecessary cluster resources.
|
||||||
|
|
||||||
|
MRAPs solve this by providing pattern-based activation of
|
||||||
|
ManagedResourceDefinitions, letting you choose which provider resources to
|
||||||
|
enable.
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## How MRAPs work
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
MRAPs contain activation patterns that match ManagedResourceDefinition names.
|
||||||
|
When you create or update an MRAP, Crossplane:
|
||||||
|
|
||||||
|
1. **Lists all MRDs** in the cluster
|
||||||
|
2. **Matches MRD names** against the activation patterns
|
||||||
|
3. **Activates matching MRDs** by setting their `state` to `Active`
|
||||||
|
4. **Updates the MRAP status** with the list of activated resources
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: aws-core-resources
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.m.crossplane.io # Modern v2 style S3 buckets
|
||||||
|
- instances.rds.aws.m.crossplane.io # Modern v2 style RDS instances
|
||||||
|
- "*.ec2.aws.m.crossplane.io" # All modern v2 style EC2 resources
|
||||||
|
```
|
||||||
|
|
||||||
|
When you apply this MRAP, Crossplane activates the specified S3 Bucket, RDS
|
||||||
|
Instance, and all EC2 resources, leaving other AWS resources inactive.
|
||||||
|
|
||||||
|
## Key features
|
||||||
|
|
||||||
|
- **Pattern-based matching**: Use wildcards to activate groups of resources
|
||||||
|
- **Multiple policy support**: Different MRAPs can activate different resource
|
||||||
|
sets
|
||||||
|
- **Status tracking**: See which resources each policy activated
|
||||||
|
- **Automatic activation**: New MRDs matching existing patterns activate
|
||||||
|
automatically
|
||||||
|
|
||||||
|
## Pattern matching
|
||||||
|
|
||||||
|
### Exact matching
|
||||||
|
|
||||||
|
Specify complete MRD names for precise control:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.m.crossplane.io
|
||||||
|
- databases.rds.aws.m.crossplane.io
|
||||||
|
- clusters.eks.aws.m.crossplane.io
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wildcard patterns
|
||||||
|
|
||||||
|
Use `*` wildcards to match multiple resources:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*.s3.aws.m.crossplane.io" # All S3 resources
|
||||||
|
- "*.ec2.aws.m.crossplane.io" # All EC2 resources
|
||||||
|
- "*.rds.aws.m.crossplane.io" # All RDS databases
|
||||||
|
```
|
||||||
|
|
||||||
|
{{<hint "important">}}
|
||||||
|
MRAPs use prefix-only wildcards, not full regular expressions. Only `*` at
|
||||||
|
the beginning of a pattern works (for example, `*.s3.aws.m.crossplane.io`).
|
||||||
|
Patterns like `s3.*.aws.m.crossplane.io` or `*.s3.*` aren't valid.
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
{{<hint "tip">}}
|
||||||
|
You can mix exact names and wildcards for flexible activation:
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.m.crossplane.io # Exact S3 buckets
|
||||||
|
- "*.ec2.aws.m.crossplane.io" # All EC2 resources
|
||||||
|
- clusters.eks.aws.m.crossplane.io # Exact EKS clusters
|
||||||
|
```
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
## Legacy and modern resource versions
|
||||||
|
|
||||||
|
Crossplane v2 supports two styles of managed resources:
|
||||||
|
|
||||||
|
- **Modern v2 style** (recommended): Use `*.m.crossplane.io` domains for
|
||||||
|
namespaced managed resources with better isolation and security
|
||||||
|
- **Legacy v1 style**: Use `*.crossplane.io` domains for cluster-scoped
|
||||||
|
managed resources (maintained for backward compatibility)
|
||||||
|
|
||||||
|
### Activating modern resources
|
||||||
|
|
||||||
|
Most examples in this guide use modern v2 style resources:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.m.crossplane.io # Modern v2 S3 bucket
|
||||||
|
- "*.ec2.aws.m.crossplane.io" # All modern v2 EC2 resources
|
||||||
|
```
|
||||||
|
|
||||||
|
### Activating legacy resources
|
||||||
|
|
||||||
|
To activate legacy v1 style resources, use patterns without `.m`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.crossplane.io # Legacy v1 S3 bucket
|
||||||
|
- "*.ec2.aws.crossplane.io" # All legacy v1 EC2 resources
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mixed activation
|
||||||
|
|
||||||
|
You can activate both modern and legacy resources in the same MRAP:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*.aws.m.crossplane.io" # All modern AWS resources
|
||||||
|
- "*.aws.crossplane.io" # All legacy AWS resources
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common activation strategies
|
||||||
|
|
||||||
|
### Activate everything (default behavior)
|
||||||
|
|
||||||
|
The Crossplane Helm chart creates a default MRAP that activates all resources:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*" # Activate all MRDs
|
||||||
|
```
|
||||||
|
|
||||||
|
You can customize this during installation:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Disable default activations entirely
|
||||||
|
helm install crossplane crossplane-stable/crossplane \
|
||||||
|
--set provider.defaultActivations={}
|
||||||
|
|
||||||
|
# Or provide custom default activations
|
||||||
|
helm install crossplane crossplane-stable/crossplane \
|
||||||
|
--set provider.defaultActivations={\
|
||||||
|
"*.s3.aws.m.crossplane.io","*.ec2.aws.m.crossplane.io"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Provider-specific activation
|
||||||
|
|
||||||
|
Activate all resources from specific providers:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: aws-provider-resources
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*.aws.crossplane.io" # All AWS resources
|
||||||
|
- "*.aws.m.crossplane.io" # All AWS managed resources (v2 style)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service-specific activation
|
||||||
|
|
||||||
|
Activate resources for specific cloud services:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: storage-and-compute
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*.s3.aws.m.crossplane.io" # AWS S3 resources
|
||||||
|
- "*.ec2.aws.m.crossplane.io" # AWS EC2 resources
|
||||||
|
- "*.storage.gcp.m.crossplane.io" # GCP Storage resources
|
||||||
|
- "*.compute.gcp.m.crossplane.io" # GCP Compute resources
|
||||||
|
```
|
||||||
|
|
||||||
|
### Minimal activation
|
||||||
|
|
||||||
|
Activate only the resources you know you need:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: minimal-footprint
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.m.crossplane.io # Just S3 buckets
|
||||||
|
- instances.ec2.aws.m.crossplane.io # Just EC2 instances
|
||||||
|
- databases.rds.aws.m.crossplane.io # Just RDS databases
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## Multiple MRAPs
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
You can have multiple MRAPs in your cluster. Crossplane processes all MRAPs
|
||||||
|
together and activates any MRD that matches at least one pattern.
|
||||||
|
|
||||||
|
### Team-based activation
|
||||||
|
|
||||||
|
Different teams can manage their own activation policies:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Storage team MRAP
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: storage-team
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*.s3.aws.m.crossplane.io"
|
||||||
|
- "*.storage.gcp.m.crossplane.io"
|
||||||
|
---
|
||||||
|
# Database team MRAP
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: database-team
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- "*.rds.aws.m.crossplane.io"
|
||||||
|
- "*.sql.gcp.m.crossplane.io"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration package activation
|
||||||
|
|
||||||
|
Configuration packages can include MRAPs to declare their resource dependencies:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# In your Configuration package
|
||||||
|
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||||
|
kind: ManagedResourceActivationPolicy
|
||||||
|
metadata:
|
||||||
|
name: web-platform-dependencies
|
||||||
|
spec:
|
||||||
|
activate:
|
||||||
|
- buckets.s3.aws.m.crossplane.io # For static assets
|
||||||
|
- instances.ec2.aws.m.crossplane.io # For web servers
|
||||||
|
- databases.rds.aws.m.crossplane.io # For application data
|
||||||
|
- certificates.acm.aws.m.crossplane.io # For HTTPS
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## Working with MRAPs
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### Creating MRAPs
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
Apply an MRAP like any Kubernetes resource:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f my-activation-policy.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### Viewing MRAPs
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
List all MRAPs:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get managedresourceactivationpolicies
|
||||||
|
```
|
||||||
|
|
||||||
|
View MRAP details and status:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl describe mrap aws-core-resources
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checking activation status
|
||||||
|
|
||||||
|
MRAPs track which resources they've activated:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- type: Healthy
|
||||||
|
status: "True"
|
||||||
|
reason: Running
|
||||||
|
activated:
|
||||||
|
- buckets.s3.aws.m.crossplane.io
|
||||||
|
- instances.ec2.aws.m.crossplane.io
|
||||||
|
- instances.rds.aws.m.crossplane.io
|
||||||
|
- securitygroups.ec2.aws.m.crossplane.io
|
||||||
|
- subnets.ec2.aws.m.crossplane.io
|
||||||
|
- vpcs.ec2.aws.m.crossplane.io
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## MRAP status conditions
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
### Healthy condition
|
||||||
|
|
||||||
|
- **`Healthy: True, Reason: Running`**: MRAP works
|
||||||
|
- **`Healthy: Unknown, Reason: EncounteredErrors`**: Some MRDs failed to
|
||||||
|
activate
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## Troubleshooting MRAPs
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### MRAP exists but resources aren't activated
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Colons = NO -->
|
||||||
|
**Symptoms**: MRAP shows `activated: []` or missing expected resources
|
||||||
|
<!-- vale Google.Colons = YES -->
|
||||||
|
|
||||||
|
**Causes and solutions:**
|
||||||
|
|
||||||
|
1. **Pattern doesn't match MRD names**
|
||||||
|
```shell
|
||||||
|
# List available MRDs
|
||||||
|
kubectl get mrds
|
||||||
|
|
||||||
|
# Check your pattern matches
|
||||||
|
kubectl get mrds -o name | grep "your-pattern"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **MRDs don't exist yet**
|
||||||
|
- Install the required provider first
|
||||||
|
- Providers create MRDs when they start
|
||||||
|
|
||||||
|
3. **Provider doesn't support activation**
|
||||||
|
```shell
|
||||||
|
# Check provider capabilities
|
||||||
|
kubectl get providerrevision <provider-revision-name> \
|
||||||
|
-o jsonpath='{.status.capabilities}'
|
||||||
|
# Look for "safe-start"
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### MRAP shows activation errors
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Colons = NO -->
|
||||||
|
**Symptoms**: MRAP has `Healthy: Unknown` status with errors
|
||||||
|
<!-- vale Google.Colons = YES -->
|
||||||
|
|
||||||
|
**Status condition example:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
conditions:
|
||||||
|
- type: Healthy
|
||||||
|
status: "Unknown"
|
||||||
|
reason: EncounteredErrors
|
||||||
|
message: "failed to activate 2 of 5 ManagedResourceDefinitions"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution**: select MRAP events for specific failure details:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl describe mrap <name>
|
||||||
|
# Look at the Events section for activation errors
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resources activate when you don't expect them to
|
||||||
|
|
||||||
|
**Symptoms**: more resources are active than expected
|
||||||
|
|
||||||
|
**Cause**: multiple MRAPs with overlapping patterns (this is normal behavior)
|
||||||
|
|
||||||
|
**Solution**: review all MRAP patterns to understand which policies are
|
||||||
|
activating which resources
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# List all MRAP activation patterns
|
||||||
|
kubectl get mrap \
|
||||||
|
-o jsonpath='{range .items[*]}{.metadata.name}: {.spec.activate}{"\n"}{end}'
|
||||||
|
|
||||||
|
# Check which MRAPs activated each resource
|
||||||
|
kubectl get mrap \
|
||||||
|
-o jsonpath='{range .items[*]}{.metadata.name}: {.status.activated}{"\n"}{end}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best practices
|
||||||
|
|
||||||
|
MRAPs are additive - multiple MRAPs can activate the same resource without
|
||||||
|
conflicts. This enables team-based activation strategies and Configuration
|
||||||
|
package dependencies.
|
||||||
|
|
||||||
|
<!-- vale alex.ProfanityUnlikely = NO -->
|
||||||
|
1. **Start specific, broaden as needed** - Begin with exact resource names,
|
||||||
|
add wildcards only when beneficial for maintainability
|
||||||
|
2. **Plan for provider evolution** - Design wildcard patterns that
|
||||||
|
accommodate new resources as providers add them (for example,
|
||||||
|
`*.s3.aws.m.crossplane.io` works for future S3 resources)
|
||||||
|
3. **Group related resources logically** - Create MRAPs that activate
|
||||||
|
resources teams actually use together
|
||||||
|
4. **Include activation dependencies in Configuration packages** -
|
||||||
|
Configuration packages should declare what MRDs they need rather than
|
||||||
|
assuming resources are available
|
||||||
|
5. **Use conservative patterns in shared environments** - Avoid overly broad
|
||||||
|
wildcards that activate unnecessary resources when multiple teams share
|
||||||
|
providers
|
||||||
|
<!-- vale alex.ProfanityUnlikely = YES -->
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
- Learn about
|
||||||
|
[ManagedResourceDefinitions]({{<ref "managed-resource-definitions">}})
|
||||||
|
to understand what MRAPs activate
|
||||||
|
- See the
|
||||||
|
[disabling unused managed resources guide]({{<ref "../guides/disabling-unused-managed-resources">}})
|
||||||
|
for step-by-step implementation
|
||||||
|
- Check the [API reference]({{<ref "../api">}}) for complete MRAP schema
|
||||||
|
documentation
|
||||||
|
|
@ -0,0 +1,377 @@
|
||||||
|
---
|
||||||
|
title: Managed Resource Definitions
|
||||||
|
weight: 15
|
||||||
|
state: alpha
|
||||||
|
alphaVersion: 2.0
|
||||||
|
description: ManagedResourceDefinitions enable selective activation of provider
|
||||||
|
resources and reduce CRD overhead
|
||||||
|
---
|
||||||
|
|
||||||
|
{{<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.
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## The CRD scaling problem
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
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 managed` must 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.
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## How MRDs work
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
An MRD contains the same schema as a CRD but adds two key fields:
|
||||||
|
|
||||||
|
- **`connectionDetails`**: Documents what connection secrets the resource
|
||||||
|
provides
|
||||||
|
- **`state`**: 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.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 `Inactive` to `Active` but not
|
||||||
|
back
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## MRD states
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
state: Inactive # Default for all MRDs
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
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>}}
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
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.
|
||||||
|
<!-- vale write-good.Weasel = YES -->
|
||||||
|
<!-- vale gitlab.CurrentStatus = YES -->
|
||||||
|
<!-- vale write-good.Passive = YES -->
|
||||||
|
{{</hint>}}
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## Working with MRDs
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### Viewing MRDs
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
List all MRDs in your cluster:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get managedresourcedefinitions
|
||||||
|
```
|
||||||
|
|
||||||
|
View MRD details:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl describe mrd buckets.s3.aws.m.crossplane.io
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### Checking MRD status
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
MRDs provide status information about their lifecycle:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- type: Established
|
||||||
|
status: "False"
|
||||||
|
reason: InactiveManagedResource
|
||||||
|
message: "ManagedResourceDefinition is inactive"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Status conditions:**
|
||||||
|
|
||||||
|
- **`Established: False, Reason: InactiveManagedResource`**: MRD is inactive,
|
||||||
|
no CRD created
|
||||||
|
- **`Established: Unknown, Reason: PendingManagedResource`**: Crossplane is
|
||||||
|
creating the CRD
|
||||||
|
- **`Established: True, Reason: EstablishedManagedResource`**: CRD exists and
|
||||||
|
is ready
|
||||||
|
- **`Healthy: True, Reason: Running`**: MRD controller operating
|
||||||
|
- **`Healthy: Unknown, Reason: EncounteredErrors`**: MRD controller
|
||||||
|
experiencing issues
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### Manually activating MRDs
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
You can manually activate an MRD by changing its state:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 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: Inactive` by default
|
||||||
|
- Support selective activation via
|
||||||
|
[ManagedResourceActivationPolicies]({{<ref "managed-resource-activation-policies">}})
|
||||||
|
- Reduced resource overhead for unused resources
|
||||||
|
- Provider can start without all CRDs being active
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# 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>}}
|
||||||
|
|
||||||
|
### Providers without `safe-start` capability
|
||||||
|
- MRDs start with `state: Active` by default (legacy behavior)
|
||||||
|
- All CRDs become available for backward compatibility
|
||||||
|
- Full resource overhead like traditional providers
|
||||||
|
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
## Troubleshooting MRDs
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### MRD exists but no CRD appears
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Colons = NO -->
|
||||||
|
**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 -->
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Check MRD state
|
||||||
|
kubectl get mrd <name> -o jsonpath='{.spec.state}'
|
||||||
|
|
||||||
|
# Activate if needed
|
||||||
|
kubectl patch mrd <name> --type='merge' -p='{"spec":{"state":"Active"}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- vale Google.Headings = NO -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = NO -->
|
||||||
|
### MRD activation fails
|
||||||
|
<!-- vale Google.Headings = YES -->
|
||||||
|
<!-- vale Microsoft.HeadingAcronyms = YES -->
|
||||||
|
|
||||||
|
<!-- vale Google.Colons = NO -->
|
||||||
|
**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 -->
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl describe mrd <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Other status conditions for troubleshooting:**
|
||||||
|
- **`Established: False, Reason: BlockedManagedResourceActivationPolicy`**:
|
||||||
|
Blocked by activation policy issues
|
||||||
|
- **`Established: False, Reason: TerminatingManagedResource`**: Crossplane is
|
||||||
|
deleting the MRD
|
||||||
|
|
||||||
|
**Common events you might see:**
|
||||||
|
- `Normal CreateCustomResourceDefinition` - CRD successfully created
|
||||||
|
- `Normal UpdateCustomResourceDefinition` - CRD successfully updated
|
||||||
|
- `Warning CreateCustomResourceDefinition` - CRD creation failed
|
||||||
|
- `Warning UpdateCustomResourceDefinition` - CRD update failed
|
||||||
|
- `Warning 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
|
||||||
|
|
||||||
|
<!-- vale Google.Colons = NO -->
|
||||||
|
**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 -->
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Check if provider supports late activation
|
||||||
|
kubectl get providerrevision <provider-revision-name> \
|
||||||
|
-o jsonpath='{.status.capabilities}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Look for the `safe-start` capability.
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
- Learn about
|
||||||
|
[ManagedResourceActivationPolicies]({{<ref "managed-resource-activation-policies">}})
|
||||||
|
for systematic resource activation
|
||||||
|
- See the
|
||||||
|
[disabling unused managed resources guide]({{<ref "../guides/disabling-unused-managed-resources">}})
|
||||||
|
for practical implementation
|
||||||
|
- Check the [API reference]({{<ref "../api">}}) for complete MRD schema
|
||||||
|
documentation
|
||||||
|
|
@ -454,6 +454,8 @@ password: 27 bytes
|
||||||
{{<hint "important" >}}
|
{{<hint "important" >}}
|
||||||
The Provider determines the data written to the Secret object. Refer to the
|
The Provider determines the data written to the Secret object. Refer to the
|
||||||
specific Provider documentation for the generated Secret data.
|
specific Provider documentation for the generated Secret data.
|
||||||
|
|
||||||
|
[ManagedResourceDefinitions]({{<ref "managed-resource-definitions">}}) can document what connection details a managed resource provides, though most providers don't yet populate this information.
|
||||||
{{< /hint >}}
|
{{< /hint >}}
|
||||||
|
|
||||||
## Annotations
|
## Annotations
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: CronOperation
|
title: Cron Operations
|
||||||
weight: 120
|
weight: 120
|
||||||
state: alpha
|
state: alpha
|
||||||
alphaVersion: 2.0
|
alphaVersion: 2.0
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Operation
|
title: Operations
|
||||||
weight: 110
|
weight: 110
|
||||||
state: alpha
|
state: alpha
|
||||||
alphaVersion: 2.0
|
alphaVersion: 2.0
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: WatchOperation
|
title: Watch Operations
|
||||||
weight: 130
|
weight: 130
|
||||||
state: alpha
|
state: alpha
|
||||||
alphaVersion: 2.0
|
alphaVersion: 2.0
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,11 @@ deprecate and remove cluster scoped MRs at a future date.
|
||||||
Read more about Crossplane v2's [backward compatibility](#backward-compatibility).
|
Read more about Crossplane v2's [backward compatibility](#backward-compatibility).
|
||||||
{{</hint>}}
|
{{</hint>}}
|
||||||
|
|
||||||
|
Crossplane v2 also introduces
|
||||||
|
[managed resource definitions]({{<ref "../managed-resources/managed-resource-definitions">}})
|
||||||
|
for selective activation of provider resources, reducing cluster overhead by
|
||||||
|
installing only the managed resources you actually need.
|
||||||
|
|
||||||
## Compose any resource
|
## Compose any resource
|
||||||
|
|
||||||
Crossplane v2 isn't opinionated about using composition together with managed
|
Crossplane v2 isn't opinionated about using composition together with managed
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue