mirror of https://github.com/crossplane/docs.git
first draft of MRD documentation based on the spec and PRs related to MRD/MRAP/SafeStart
Signed-off-by: Scott Nichols <n3wscott@upbound.io>
This commit is contained in:
parent
704d5dfe38
commit
3fcc4473a9
|
|
@ -0,0 +1,530 @@
|
|||
---
|
||||
title: Get Started with Managed Resource Definitions
|
||||
weight: 220
|
||||
description: Learn how to use MRDs and activation policies to optimize your Crossplane installation
|
||||
---
|
||||
|
||||
This guide shows how to use Managed Resource Definitions (MRDs) and activation
|
||||
policies to control which managed resources are available in your cluster.
|
||||
You install a provider, examine its MRDs, and use policies to activate only
|
||||
the resources you need.
|
||||
|
||||
{{< hint "tip" >}}
|
||||
This guide demonstrates the performance and discovery benefits of MRDs by
|
||||
working with a subset of AWS resources rather than installing hundreds of CRDs.
|
||||
{{< /hint >}}
|
||||
|
||||
By the end of this guide, you understand how to:
|
||||
* Examine MRDs created by provider packages
|
||||
* Use activation policies to control resource availability
|
||||
* Discover connection details through MRD schemas
|
||||
* Optimize cluster performance by activating only needed resources
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This guide requires:
|
||||
|
||||
* A Kubernetes cluster with at least 2 GB of RAM
|
||||
* Crossplane v2.0+ [installed on the cluster]({{< ref "install" >}})
|
||||
* `kubectl` configured to access your cluster
|
||||
|
||||
## Understand the default activation policy
|
||||
|
||||
Before installing providers, it's important to understand Crossplane's default
|
||||
activation behavior. Crossplane creates a default ManagedResourceActivationPolicy
|
||||
that, by default, activates **all** managed resources with a `"*"` pattern.
|
||||
|
||||
{{< hint "important" >}}
|
||||
The default `"*"` activation pattern defeats the performance benefits of
|
||||
SafeStart by activating all resources. For this tutorial, we work with the
|
||||
default behavior, but production setups should use more selective activation.
|
||||
{{< /hint >}}
|
||||
|
||||
Check if you have a default activation policy:
|
||||
|
||||
```shell
|
||||
kubectl get mrap crossplane-default-activation-policy -o yaml
|
||||
```
|
||||
|
||||
You can modify the default activation policy directly:
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "Edit Existing Policy" >}}
|
||||
```shell
|
||||
# Permanently disable by using a non-matching pattern
|
||||
kubectl patch mrap crossplane-default-activation-policy --type='merge' \
|
||||
-p='{"spec":{"activations":["nonexistent.example.com"]}}'
|
||||
|
||||
# Or remove all activations entirely
|
||||
kubectl patch mrap crossplane-default-activation-policy --type='merge' \
|
||||
-p='{"spec":{"activations":[]}}'
|
||||
```
|
||||
|
||||
{{< hint "note" >}}
|
||||
Changes to the default policy are permanent. After the policy exists, Crossplane
|
||||
won't modify it, even if you change Helm values.
|
||||
{{< /hint >}}
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "Reset with Helm Values" >}}
|
||||
```shell
|
||||
# Delete the default policy and restart Crossplane to recreate from Helm values
|
||||
kubectl delete mrap crossplane-default-activation-policy
|
||||
helm upgrade crossplane crossplane-stable/crossplane \
|
||||
--set provider.defaultActivations=null \
|
||||
--namespace crossplane-system --reuse-values
|
||||
kubectl rollout restart deployment/crossplane -n crossplane-system
|
||||
```
|
||||
|
||||
This approach lets you use Helm chart values to control the default policy.
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
{{< hint "tip" >}}
|
||||
Learn more about configuring default activation policies during installation
|
||||
and best practices in the [MRD activation policies guide]({{< ref "../guides/mrd-activation-policies#default-activation-policy" >}}).
|
||||
{{< /hint >}}
|
||||
|
||||
## Install a SafeStart provider
|
||||
|
||||
Now install a provider that supports SafeStart. This provider creates MRDs
|
||||
that activation policies control.
|
||||
|
||||
```yaml
|
||||
apiVersion: pkg.crossplane.io/v1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: provider-aws
|
||||
spec:
|
||||
package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.45.0
|
||||
```
|
||||
|
||||
Apply this configuration:
|
||||
|
||||
```shell
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: pkg.crossplane.io/v1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: provider-aws
|
||||
spec:
|
||||
package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.45.0
|
||||
EOF
|
||||
```
|
||||
|
||||
Wait for the provider to become healthy:
|
||||
|
||||
```shell
|
||||
kubectl get providers
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME INSTALLED HEALTHY PACKAGE AGE
|
||||
provider-aws True True xpkg.upbound.io/crossplane-contrib/provider-aws 2m
|
||||
```
|
||||
|
||||
## Examine the MRDs
|
||||
|
||||
List the MRDs created by the provider:
|
||||
|
||||
```shell
|
||||
kubectl get mrds
|
||||
```
|
||||
|
||||
The MRD states depend on your default activation policy:
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "With Default Activation (default)" >}}
|
||||
If you kept the default `"*"` activation pattern:
|
||||
|
||||
```shell
|
||||
NAME STATE AGE
|
||||
buckets.s3.aws.crossplane.io Active 2m
|
||||
instances.ec2.aws.crossplane.io Active 2m
|
||||
databases.rds.aws.crossplane.io Active 2m
|
||||
clusters.eks.aws.crossplane.io Active 2m
|
||||
# ... many more, all Active
|
||||
```
|
||||
|
||||
The default policy activates all MRDs, so SafeStart providers behave like
|
||||
traditional providers.
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "With Disabled Default Activation" >}}
|
||||
If you disabled default activation:
|
||||
|
||||
```shell
|
||||
NAME STATE AGE
|
||||
buckets.s3.aws.crossplane.io Inactive 2m
|
||||
instances.ec2.aws.crossplane.io Inactive 2m
|
||||
databases.rds.aws.crossplane.io Inactive 2m
|
||||
clusters.eks.aws.crossplane.io Inactive 2m
|
||||
# ... many more, all Inactive
|
||||
```
|
||||
|
||||
This demonstrates true SafeStart behavior where resources must be explicitly
|
||||
activated.
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
{{< hint "note" >}}
|
||||
For the rest of this tutorial, we assume you have default activation
|
||||
disabled to demonstrate selective activation. If you have default activation
|
||||
enabled, the MRDs are already active.
|
||||
{{< /hint >}}
|
||||
|
||||
Examine a specific MRD to understand its schema and connection details:
|
||||
|
||||
```shell
|
||||
kubectl get mrd instances.ec2.aws.crossplane.io -o yaml
|
||||
```
|
||||
|
||||
Look for the `connectionDetails` section:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
connectionDetails:
|
||||
- description: The public IP address assigned to the instance
|
||||
name: public_ip
|
||||
type: string
|
||||
- description: The private IP address assigned to the instance
|
||||
name: private_ip
|
||||
type: string
|
||||
- description: The public DNS name assigned to the instance
|
||||
name: public_dns
|
||||
type: string
|
||||
```
|
||||
|
||||
## Verify CRD creation behavior
|
||||
|
||||
The presence of CRDs depends on whether MRDs are active:
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "With Default Activation (default)" >}}
|
||||
Because MRDs are active due to the default `"*"` policy, CRDs exist:
|
||||
|
||||
```shell
|
||||
kubectl get crds | grep aws.crossplane.io | wc -l
|
||||
```
|
||||
|
||||
This shows many CRDs (100+), demonstrating that active MRDs
|
||||
create CRDs immediately.
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "With Disabled Default Activation" >}}
|
||||
Because the MRDs are inactive, no CRDs should exist for AWS resources:
|
||||
|
||||
```shell
|
||||
kubectl get crds | grep aws.crossplane.io
|
||||
```
|
||||
|
||||
This should return no results, demonstrating that inactive MRDs don't create
|
||||
CRDs in your cluster.
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
## Create an activation policy
|
||||
|
||||
Create a ManagedResourceActivationPolicy to activate specific AWS resources:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: aws-demo-resources
|
||||
spec:
|
||||
activations:
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- "*.rds.aws.crossplane.io"
|
||||
```
|
||||
|
||||
Apply the policy:
|
||||
|
||||
```shell
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: aws-demo-resources
|
||||
spec:
|
||||
activations:
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- "*.rds.aws.crossplane.io"
|
||||
EOF
|
||||
```
|
||||
|
||||
This policy activates:
|
||||
* EC2 instances (exact match)
|
||||
* S3 buckets (exact match)
|
||||
* All RDS resources (wildcard match)
|
||||
|
||||
## Verify activation
|
||||
|
||||
Check that the specified MRDs are now active:
|
||||
|
||||
```shell
|
||||
kubectl get mrds instances.ec2.aws.crossplane.io buckets.s3.aws.crossplane.io
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME STATE AGE
|
||||
instances.ec2.aws.crossplane.io Active 5m
|
||||
buckets.s3.aws.crossplane.io Active 5m
|
||||
```
|
||||
|
||||
List all RDS MRDs to see they're also active:
|
||||
|
||||
```shell
|
||||
kubectl get mrds | grep rds
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME STATE AGE
|
||||
clusters.rds.aws.crossplane.io Active 5m
|
||||
databases.rds.aws.crossplane.io Active 5m
|
||||
dbinstances.rds.aws.crossplane.io Active 5m
|
||||
# ... other RDS resources
|
||||
```
|
||||
|
||||
## Verify CRDs are created
|
||||
|
||||
Now that MRDs are active, CRDs should exist:
|
||||
|
||||
```shell
|
||||
kubectl get crds | grep -E "(instances.ec2|buckets.s3|rds)" | head -5
|
||||
```
|
||||
|
||||
```shell
|
||||
buckets.s3.aws.crossplane.io 2024-01-15T10:30:00Z
|
||||
clusters.rds.aws.crossplane.io 2024-01-15T10:30:00Z
|
||||
databases.rds.aws.crossplane.io 2024-01-15T10:30:00Z
|
||||
dbinstances.rds.aws.crossplane.io 2024-01-15T10:30:00Z
|
||||
instances.ec2.aws.crossplane.io 2024-01-15T10:30:00Z
|
||||
```
|
||||
|
||||
## Create a managed resource
|
||||
|
||||
Now you can create managed resources using the active MRDs. Create an S3 bucket:
|
||||
|
||||
```yaml
|
||||
apiVersion: s3.aws.crossplane.io/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: my-demo-bucket
|
||||
spec:
|
||||
forProvider:
|
||||
region: us-east-1
|
||||
providerConfigRef:
|
||||
name: default
|
||||
```
|
||||
|
||||
{{< hint "note" >}}
|
||||
This example assumes you have AWS credentials configured. See the
|
||||
[AWS Provider documentation]({{< ref "../guides/aws-provider" >}}) for
|
||||
authentication setup.
|
||||
{{< /hint >}}
|
||||
|
||||
```shell
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: s3.aws.crossplane.io/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: my-demo-bucket
|
||||
spec:
|
||||
forProvider:
|
||||
region: us-east-1
|
||||
providerConfigRef:
|
||||
name: default
|
||||
EOF
|
||||
```
|
||||
|
||||
## Test inactive resources
|
||||
|
||||
Try to create a managed resource for an inactive MRD, like EKS clusters:
|
||||
|
||||
```shell
|
||||
kubectl get mrd clusters.eks.aws.crossplane.io
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME STATE AGE
|
||||
clusters.eks.aws.crossplane.io Inactive 8m
|
||||
```
|
||||
|
||||
Attempting to create an EKS cluster fails because the CRD doesn't exist:
|
||||
|
||||
```shell
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: eks.aws.crossplane.io/v1alpha1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: test-cluster
|
||||
spec:
|
||||
forProvider:
|
||||
region: us-east-1
|
||||
version: "1.21"
|
||||
EOF
|
||||
```
|
||||
|
||||
```shell
|
||||
error validating data: ValidationError(Cluster): unknown field "apiVersion" in io.k8s.api.core.v1.Cluster
|
||||
```
|
||||
|
||||
## Expand activation with wildcards
|
||||
|
||||
Add more resources using wildcard patterns. Update your activation policy:
|
||||
|
||||
```shell
|
||||
kubectl patch mrap aws-demo-resources --type merge -p '{
|
||||
"spec": {
|
||||
"activations": [
|
||||
"instances.ec2.aws.crossplane.io",
|
||||
"buckets.s3.aws.crossplane.io",
|
||||
"*.rds.aws.crossplane.io",
|
||||
"*.eks.aws.crossplane.io"
|
||||
]
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Verify EKS resources are now active:
|
||||
|
||||
```shell
|
||||
kubectl get mrds | grep eks
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME STATE AGE
|
||||
clusters.eks.aws.crossplane.io Active 10m
|
||||
nodegroups.eks.aws.crossplane.io Active 10m
|
||||
```
|
||||
|
||||
## Examine activation policy status
|
||||
|
||||
Check which MRDs your policy has activated:
|
||||
|
||||
```shell
|
||||
kubectl get mrap aws-demo-resources -o yaml
|
||||
```
|
||||
|
||||
Look for the `status.activated` field:
|
||||
|
||||
```yaml
|
||||
status:
|
||||
activated:
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- clusters.rds.aws.crossplane.io
|
||||
- databases.rds.aws.crossplane.io
|
||||
- clusters.eks.aws.crossplane.io
|
||||
- nodegroups.eks.aws.crossplane.io
|
||||
# ... other activated MRDs
|
||||
```
|
||||
|
||||
## Performance comparison
|
||||
|
||||
Compare the resource usage with traditional provider installation:
|
||||
|
||||
**Without MRDs (traditional):**
|
||||
- All ~200 AWS CRDs created immediately
|
||||
- Higher memory usage in kube-apiserver
|
||||
- Longer provider installation time
|
||||
|
||||
**With MRDs and selective activation:**
|
||||
- Only activated CRDs created (~10-20 in this example)
|
||||
- Lower memory footprint
|
||||
- Faster resource discovery and management
|
||||
|
||||
Check the number of AWS CRDs currently in your cluster:
|
||||
|
||||
```shell
|
||||
kubectl get crds | grep aws.crossplane.io | wc -l
|
||||
```
|
||||
|
||||
This should be much smaller than the total number of MRDs.
|
||||
|
||||
## Multiple activation policies
|
||||
|
||||
You can create multiple MRAPs for different use cases. Create a second policy
|
||||
for development environments:
|
||||
|
||||
```shell
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: aws-dev-resources
|
||||
spec:
|
||||
activations:
|
||||
- "*.ec2.aws.crossplane.io"
|
||||
- "*.iam.aws.crossplane.io"
|
||||
EOF
|
||||
```
|
||||
|
||||
The activations from both policies are combined, giving you fine-grained
|
||||
control over resource availability.
|
||||
|
||||
## Clean up
|
||||
|
||||
Remove the demo resources:
|
||||
|
||||
```shell
|
||||
kubectl delete bucket my-demo-bucket
|
||||
kubectl delete mrap aws-demo-resources aws-dev-resources
|
||||
kubectl delete provider provider-aws
|
||||
```
|
||||
|
||||
## Production recommendations
|
||||
|
||||
For production Crossplane deployments, follow these best practices:
|
||||
|
||||
### 1. Disable default activation
|
||||
|
||||
Install Crossplane with selective activation:
|
||||
|
||||
```shell
|
||||
helm install crossplane crossplane-stable/crossplane \
|
||||
--set provider.defaultActivations=null \
|
||||
--namespace crossplane-system
|
||||
```
|
||||
|
||||
### 2. Use targeted activation policies
|
||||
|
||||
Create provider-specific policies rather than using the default `"*"` pattern:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: production-aws-resources
|
||||
spec:
|
||||
activations:
|
||||
- "instances.ec2.aws.crossplane.io"
|
||||
- "*.rds.aws.crossplane.io"
|
||||
- "buckets.s3.aws.crossplane.io"
|
||||
- "*.iam.aws.crossplane.io"
|
||||
```
|
||||
|
||||
### 3. Environment-specific policies
|
||||
|
||||
Use different activation strategies per environment:
|
||||
|
||||
* **Development**: Broad activation for experimentation
|
||||
* **Staging**: Subset of production resources for testing
|
||||
* **Production**: Minimal, specific activation for performance
|
||||
|
||||
## Next steps
|
||||
|
||||
Now that you understand MRDs and activation policies, you can:
|
||||
|
||||
* **Optimize cluster performance** by using selective activation
|
||||
* **Improve resource discovery** through MRD connection details documentation
|
||||
* **Implement environment-specific policies** for different deployment stages
|
||||
* **Plan provider adoption** using SafeStart-capable providers
|
||||
|
||||
Learn more about:
|
||||
* [MRD activation policies best practices]({{< ref "../guides/mrd-activation-policies" >}}) - Comprehensive guide including default policy configuration
|
||||
* [Managed Resource Definitions concepts]({{< ref "managed-resource-definitions" >}})
|
||||
* [Provider capabilities and SafeStart]({{< ref "../packages/provider-capabilities" >}})
|
||||
|
|
@ -0,0 +1,714 @@
|
|||
---
|
||||
title: Implementing SafeStart in Providers
|
||||
weight: 160
|
||||
description: Guide for provider developers to implement SafeStart capability
|
||||
---
|
||||
|
||||
This guide shows provider developers how to implement SafeStart capability in
|
||||
their Crossplane providers. SafeStart enables selective resource activation
|
||||
through Managed Resource Definitions (MRDs), improving performance and resource
|
||||
management.
|
||||
|
||||
{{< hint "important" >}}
|
||||
SafeStart requires Crossplane v2.0+ and involves significant provider changes.
|
||||
Plan for breaking changes and thorough testing before implementing.
|
||||
{{< /hint >}}
|
||||
|
||||
## What SafeStart provides
|
||||
|
||||
SafeStart transforms how your provider handles resource installation:
|
||||
|
||||
**Without SafeStart:**
|
||||
- All managed resources become CRDs immediately when provider installs
|
||||
- Users get all ~200 AWS resources even if they need only 5
|
||||
- Higher memory usage and slower API server responses
|
||||
|
||||
**With SafeStart:**
|
||||
- All managed resources become inactive MRDs when provider installs
|
||||
- Users activate only needed resources through policies
|
||||
- Lower resource overhead and better performance
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before implementing SafeStart, ensure you have:
|
||||
|
||||
* Provider built with Crossplane v2.0+ runtime
|
||||
* Understanding of [MRDs and activation policies]({{< ref "mrd-activation-policies" >}})
|
||||
* Test environment with Crossplane v2.0+
|
||||
* CI/CD pipeline that can build and test provider changes
|
||||
|
||||
## Implementation steps
|
||||
|
||||
### Step 1: Update provider metadata
|
||||
|
||||
Declare SafeStart capability in your provider package metadata:
|
||||
|
||||
```yaml
|
||||
apiVersion: meta.pkg.crossplane.io/v1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: provider-example
|
||||
spec:
|
||||
package: registry.example.com/provider-example:v1.0.0
|
||||
capabilities:
|
||||
- name: SafeStart
|
||||
```
|
||||
|
||||
{{< hint "tip" >}}
|
||||
Crossplane supports flexible capability matching. `SafeStart`, `safestart`,
|
||||
and `safe-start` are all recognized as the same capability.
|
||||
{{< /hint >}}
|
||||
|
||||
### Step 2: Enhance MRD generation
|
||||
|
||||
Update your MRD generation to include connection details documentation:
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "Go Controller Runtime" >}}
|
||||
```go
|
||||
// In your MRD generation code
|
||||
type ManagedResourceDefinition struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ManagedResourceDefinitionSpec `json:"spec"`
|
||||
Status ManagedResourceDefinitionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type ManagedResourceDefinitionSpec struct {
|
||||
// Standard CRD fields
|
||||
Group string `json:"group"`
|
||||
Names Names `json:"names"`
|
||||
Scope string `json:"scope"`
|
||||
|
||||
// SafeStart-specific fields
|
||||
ConnectionDetails []ConnectionDetail `json:"connectionDetails,omitempty"`
|
||||
State ResourceState `json:"state,omitempty"`
|
||||
}
|
||||
|
||||
type ConnectionDetail struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Type string `json:"type"`
|
||||
FromConnectionSecretKey string `json:"fromConnectionSecretKey,omitempty"`
|
||||
}
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "Terrajet/Upjet Provider" >}}
|
||||
```go
|
||||
// In your provider configuration
|
||||
func GetProvider() *ujconfig.Provider {
|
||||
pc := ujconfig.NewProvider([]byte(providerSchema), resourcePrefix, modulePath,
|
||||
ujconfig.WithIncludeList(ExternalNameConfigured()),
|
||||
ujconfig.WithDefaultResourceOptions(
|
||||
ExternalNameConfigurations(),
|
||||
SafeStartConfiguration(), // Add SafeStart config
|
||||
))
|
||||
|
||||
// Configure SafeStart for specific resources
|
||||
for _, configure := range []func(provider *ujconfig.Provider){
|
||||
configureConnectionDetails,
|
||||
configureMRDDocumentation,
|
||||
} {
|
||||
configure(pc)
|
||||
}
|
||||
|
||||
return pc
|
||||
}
|
||||
|
||||
func configureConnectionDetails(p *ujconfig.Provider) {
|
||||
// Example: RDS Instance connection details
|
||||
p.AddResourceConfigurator("aws_db_instance", func(r *ujconfig.Resource) {
|
||||
r.ConnectionDetails = map[string]ujconfig.ConnectionDetail{
|
||||
"endpoint": {
|
||||
Description: "The RDS instance endpoint",
|
||||
Type: "string",
|
||||
FromConnectionSecretKey: "endpoint",
|
||||
},
|
||||
"port": {
|
||||
Description: "The port on which the DB accepts connections",
|
||||
Type: "integer",
|
||||
FromConnectionSecretKey: "port",
|
||||
},
|
||||
"username": {
|
||||
Description: "The master username for the database",
|
||||
Type: "string",
|
||||
FromConnectionSecretKey: "username",
|
||||
},
|
||||
"password": {
|
||||
Description: "The master password for the database",
|
||||
Type: "string",
|
||||
FromConnectionSecretKey: "password",
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### Step 3: Handle namespaced resources
|
||||
|
||||
SafeStart works best with namespaced managed resources. Update your resources
|
||||
to support both cluster and namespaced scopes:
|
||||
|
||||
```go
|
||||
// Update resource definitions to support namespacing
|
||||
type Database struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec DatabaseSpec `json:"spec"`
|
||||
Status DatabaseStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Update your CRD generation
|
||||
//+kubebuilder:resource:scope=Namespaced
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
type Database struct {
|
||||
// ... resource definition
|
||||
}
|
||||
|
||||
// Optionally create cluster-scoped variants
|
||||
//+kubebuilder:resource:scope=Cluster
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
type ClusterDatabase struct {
|
||||
// ... same spec but cluster scoped
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Update RBAC permissions
|
||||
|
||||
SafeStart providers need additional permissions to manage CRDs dynamically:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: provider-example-system
|
||||
rules:
|
||||
# Existing provider permissions
|
||||
- apiGroups: [""]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "update", "patch"]
|
||||
- apiGroups: ["example.crossplane.io"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
|
||||
# Additional SafeStart permissions
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["apiextensions.crossplane.io"]
|
||||
resources: ["managedresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch", "update", "patch"]
|
||||
```
|
||||
|
||||
### Step 5: Implement MRD controller logic
|
||||
|
||||
Add controller logic to handle MRD activation and CRD lifecycle:
|
||||
|
||||
```go
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
xpv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/v1alpha1"
|
||||
)
|
||||
|
||||
// MRDReconciler handles MRD activation
|
||||
type MRDReconciler struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
func (r *MRDReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
|
||||
mrd := &xpv1alpha1.ManagedResourceDefinition{}
|
||||
if err := r.Get(ctx, req.NamespacedName, mrd); err != nil {
|
||||
return reconcile.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// Check if MRD should be active
|
||||
if mrd.Spec.State != nil && *mrd.Spec.State == xpv1alpha1.ResourceStateActive {
|
||||
return r.ensureCRDExists(ctx, mrd)
|
||||
}
|
||||
|
||||
// If inactive, ensure CRD is removed
|
||||
return r.ensureCRDRemoved(ctx, mrd)
|
||||
}
|
||||
|
||||
func (r *MRDReconciler) ensureCRDExists(ctx context.Context, mrd *xpv1alpha1.ManagedResourceDefinition) (reconcile.Result, error) {
|
||||
crd := &apiextv1.CustomResourceDefinition{}
|
||||
crdName := mrd.Spec.Names.Plural + "." + mrd.Spec.Group
|
||||
|
||||
err := r.Get(ctx, types.NamespacedName{Name: crdName}, crd)
|
||||
if client.IgnoreNotFound(err) != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err != nil { // CRD doesn't exist
|
||||
return r.createCRD(ctx, mrd)
|
||||
}
|
||||
|
||||
// CRD exists, ensure it's up to date
|
||||
return r.updateCRD(ctx, mrd, crd)
|
||||
}
|
||||
|
||||
func (r *MRDReconciler) createCRD(ctx context.Context, mrd *xpv1alpha1.ManagedResourceDefinition) (reconcile.Result, error) {
|
||||
crd := &apiextv1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: mrd.Spec.Names.Plural + "." + mrd.Spec.Group,
|
||||
OwnerReferences: []metav1.OwnerReference{{
|
||||
APIVersion: mrd.APIVersion,
|
||||
Kind: mrd.Kind,
|
||||
Name: mrd.Name,
|
||||
UID: mrd.UID,
|
||||
Controller: pointer.Bool(true),
|
||||
}},
|
||||
},
|
||||
Spec: mrd.Spec.CustomResourceDefinitionSpec,
|
||||
}
|
||||
|
||||
return reconcile.Result{}, r.Create(ctx, crd)
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Update build and CI processes
|
||||
|
||||
Update your build process to generate MRDs alongside CRDs:
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "Makefile" >}}
|
||||
```makefile
|
||||
# Update your Makefile to generate both CRDs and MRDs
|
||||
.PHONY: generate
|
||||
generate: controller-gen
|
||||
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
||||
$(CONTROLLER_GEN) crd:allowDangerousTypes=true paths="./..." output:crd:artifacts:config=package/crds
|
||||
$(CONTROLLER_GEN) mrd:allowDangerousTypes=true paths="./..." output:mrd:artifacts:config=package/mrds
|
||||
|
||||
# Add MRD generation tool
|
||||
MRD_GEN = $(shell pwd)/bin/mrd-gen
|
||||
.PHONY: mrd-gen
|
||||
mrd-gen: ## Download mrd-gen locally if necessary.
|
||||
$(call go-get-tool,$(MRD_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.13.0)
|
||||
|
||||
# Update package generation to include MRDs
|
||||
.PHONY: build-package
|
||||
build-package: generate
|
||||
mkdir -p package/
|
||||
cp package/crds/*.yaml package/
|
||||
cp package/mrds/*.yaml package/
|
||||
echo "# Package metadata with SafeStart capability" > package/provider.yaml
|
||||
echo "apiVersion: meta.pkg.crossplane.io/v1" >> package/provider.yaml
|
||||
echo "kind: Provider" >> package/provider.yaml
|
||||
echo "spec:" >> package/provider.yaml
|
||||
echo " capabilities:" >> package/provider.yaml
|
||||
echo " - name: SafeStart" >> package/provider.yaml
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "GitHub Actions" >}}
|
||||
```yaml
|
||||
name: Build and Test SafeStart Provider
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test-safestart:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: Run Tests
|
||||
run: make test
|
||||
|
||||
- name: Generate MRDs
|
||||
run: make generate
|
||||
|
||||
- name: Verify MRD Generation
|
||||
run: |
|
||||
if [ ! -d "package/mrds" ]; then
|
||||
echo "MRD generation failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "Generated MRDs:"
|
||||
ls -la package/mrds/
|
||||
|
||||
- name: Test SafeStart Integration
|
||||
run: |
|
||||
# Start local cluster
|
||||
make kind-up
|
||||
make install-crossplane-v2
|
||||
|
||||
# Install provider with SafeStart
|
||||
make install-provider
|
||||
|
||||
# Verify MRDs created but inactive
|
||||
kubectl get mrds
|
||||
kubectl get mrds -o jsonpath='{.items[*].spec.state}' | grep -q "Inactive"
|
||||
|
||||
# Test activation policy
|
||||
kubectl apply -f examples/activation-policy.yaml
|
||||
|
||||
# Verify resources activate
|
||||
sleep 30
|
||||
kubectl get mrds -o jsonpath='{.items[*].spec.state}' | grep -q "Active"
|
||||
|
||||
# Test resource creation
|
||||
kubectl apply -f examples/example-resource.yaml
|
||||
kubectl wait --for=condition=Ready --timeout=300s -f examples/example-resource.yaml
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### Step 7: Add connection details documentation
|
||||
|
||||
Document connection details in your MRDs to help users understand resource
|
||||
capabilities:
|
||||
|
||||
```yaml
|
||||
# Example generated MRD with connection details
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceDefinition
|
||||
metadata:
|
||||
name: databases.rds.aws.example.io
|
||||
spec:
|
||||
group: rds.aws.example.io
|
||||
names:
|
||||
kind: Database
|
||||
plural: databases
|
||||
scope: Namespaced
|
||||
|
||||
# SafeStart-specific fields
|
||||
connectionDetails:
|
||||
- name: endpoint
|
||||
description: "The RDS instance connection endpoint"
|
||||
type: string
|
||||
fromConnectionSecretKey: endpoint
|
||||
- name: port
|
||||
description: "The port number for database connections"
|
||||
type: integer
|
||||
fromConnectionSecretKey: port
|
||||
- name: username
|
||||
description: "The master username for the database"
|
||||
type: string
|
||||
fromConnectionSecretKey: username
|
||||
- name: password
|
||||
description: "The master password for the database"
|
||||
type: string
|
||||
fromConnectionSecretKey: password
|
||||
- name: ca_certificate
|
||||
description: "The CA certificate for SSL connections"
|
||||
type: string
|
||||
fromConnectionSecretKey: ca_certificate
|
||||
|
||||
# Standard CRD specification
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
# ... rest of CRD spec
|
||||
```
|
||||
|
||||
## Testing SafeStart implementation
|
||||
|
||||
### Unit testing
|
||||
|
||||
Test your MRD generation and controller logic:
|
||||
|
||||
```go
|
||||
func TestMRDGeneration(t *testing.T) {
|
||||
// Test that MRDs are generated with correct connection details
|
||||
mrd := generateMRDForResource("Database")
|
||||
|
||||
assert.Equal(t, "databases.rds.aws.example.io", mrd.Name)
|
||||
assert.NotEmpty(t, mrd.Spec.ConnectionDetails)
|
||||
|
||||
// Verify specific connection details
|
||||
endpointDetail := findConnectionDetail(mrd, "endpoint")
|
||||
assert.NotNil(t, endpointDetail)
|
||||
assert.Equal(t, "string", endpointDetail.Type)
|
||||
assert.Contains(t, endpointDetail.Description, "endpoint")
|
||||
}
|
||||
|
||||
func TestMRDActivation(t *testing.T) {
|
||||
// Test MRD activation creates CRD
|
||||
ctx := context.Background()
|
||||
mrd := &v1alpha1.ManagedResourceDefinition{
|
||||
Spec: v1alpha1.ManagedResourceDefinitionSpec{
|
||||
State: &[]v1alpha1.ResourceState{v1alpha1.ResourceStateActive}[0],
|
||||
},
|
||||
}
|
||||
|
||||
reconciler := &MRDReconciler{Client: fakeClient}
|
||||
result, err := reconciler.Reconcile(ctx, reconcile.Request{})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, result.Requeue)
|
||||
|
||||
// Verify CRD was created
|
||||
crd := &apiextv1.CustomResourceDefinition{}
|
||||
err = fakeClient.Get(ctx, types.NamespacedName{Name: "databases.rds.aws.example.io"}, crd)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
```
|
||||
|
||||
### Integration testing
|
||||
|
||||
Test SafeStart behavior in a real cluster:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Starting SafeStart integration test..."
|
||||
|
||||
# Install Crossplane v2.0
|
||||
kubectl create namespace crossplane-system
|
||||
helm install crossplane crossplane-stable/crossplane \
|
||||
--namespace crossplane-system \
|
||||
--version v2.0.0 \
|
||||
--wait
|
||||
|
||||
# Install provider with SafeStart
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: pkg.crossplane.io/v1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: provider-example
|
||||
spec:
|
||||
package: registry.example.com/provider-example:latest
|
||||
capabilities:
|
||||
- name: SafeStart
|
||||
EOF
|
||||
|
||||
# Wait for provider installation
|
||||
kubectl wait --for=condition=Healthy provider/provider-example --timeout=300s
|
||||
|
||||
# Verify MRDs created but inactive
|
||||
echo "Checking MRD states..."
|
||||
MRD_COUNT=$(kubectl get mrds --no-headers | wc -l)
|
||||
INACTIVE_COUNT=$(kubectl get mrds -o jsonpath='{.items[*].spec.state}' | grep -o "Inactive" | wc -l)
|
||||
|
||||
if [ "$MRD_COUNT" -eq "$INACTIVE_COUNT" ]; then
|
||||
echo "✓ All MRDs are inactive as expected"
|
||||
else
|
||||
echo "✗ Some MRDs are unexpectedly active"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test activation policy
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: test-policy
|
||||
spec:
|
||||
activations:
|
||||
- "databases.rds.aws.example.io"
|
||||
EOF
|
||||
|
||||
# Wait for activation
|
||||
sleep 10
|
||||
|
||||
# Verify activation worked
|
||||
ACTIVE_COUNT=$(kubectl get mrd databases.rds.aws.example.io -o jsonpath='{.spec.state}' | grep -o "Active" | wc -l)
|
||||
if [ "$ACTIVE_COUNT" -eq "1" ]; then
|
||||
echo "✓ MRD activation successful"
|
||||
else
|
||||
echo "✗ MRD activation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test resource creation
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: rds.aws.example.io/v1alpha1
|
||||
kind: Database
|
||||
metadata:
|
||||
name: test-db
|
||||
namespace: default
|
||||
spec:
|
||||
forProvider:
|
||||
engine: postgres
|
||||
region: us-east-1
|
||||
EOF
|
||||
|
||||
# Verify resource creation
|
||||
kubectl wait --for=condition=Ready database/test-db --timeout=300s --namespace default
|
||||
|
||||
echo "✓ SafeStart integration test passed"
|
||||
```
|
||||
|
||||
## Migration considerations
|
||||
|
||||
### For existing users
|
||||
|
||||
When you add SafeStart to an existing provider:
|
||||
|
||||
**Breaking change considerations:**
|
||||
- Existing installations will continue working (backward compatibility)
|
||||
- New installations will have inactive MRDs by default
|
||||
- Users need activation policies for new installations
|
||||
|
||||
**Migration strategy:**
|
||||
```yaml
|
||||
# Provide migration documentation like:
|
||||
# For users upgrading to SafeStart-enabled provider v2.0:
|
||||
|
||||
# 1. Existing resources continue working unchanged
|
||||
# 2. For new installations, create activation policy:
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: legacy-compatibility
|
||||
spec:
|
||||
activations:
|
||||
- "*.aws.example.io" # Activate all resources (legacy behavior)
|
||||
```
|
||||
|
||||
### Version compatibility matrix
|
||||
|
||||
Document version compatibility clearly:
|
||||
|
||||
| Provider Version | Crossplane Version | SafeStart Support | Notes |
|
||||
|------------------|-------------------|------------------|-------|
|
||||
| v1.x | v1.x - v2.x | No | Legacy CRD-only mode |
|
||||
| v2.0 | v2.0+ | Yes | Full SafeStart support |
|
||||
| v2.1 | v2.0+ | Yes | Enhanced MRD features |
|
||||
|
||||
## Documentation requirements
|
||||
|
||||
Update your provider documentation to include:
|
||||
|
||||
### README updates
|
||||
|
||||
```markdown
|
||||
# Provider Example
|
||||
|
||||
## SafeStart Support
|
||||
|
||||
This provider supports SafeStart capability, which provides:
|
||||
- Selective resource activation
|
||||
- Improved performance for large providers
|
||||
- Connection details documentation
|
||||
|
||||
### Quick Start with SafeStart
|
||||
|
||||
1. Install the provider:
|
||||
```yaml
|
||||
apiVersion: pkg.crossplane.io/v1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: provider-example
|
||||
spec:
|
||||
package: registry.example.com/provider-example:v2.0.0
|
||||
```
|
||||
|
||||
2. Create activation policy:
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: example-resources
|
||||
spec:
|
||||
activations:
|
||||
- "databases.rds.aws.example.io"
|
||||
- "*.s3.aws.example.io"
|
||||
```
|
||||
|
||||
3. Create resources normally - only activated resources work.
|
||||
```
|
||||
|
||||
### Connection details documentation
|
||||
|
||||
Document what connection details each resource provides:
|
||||
|
||||
```markdown
|
||||
## Connection Details Reference
|
||||
|
||||
### Database (`databases.rds.aws.example.io`)
|
||||
- `endpoint` (string): RDS instance connection endpoint
|
||||
- `port` (integer): Database connection port
|
||||
- `username` (string): Master database username
|
||||
- `password` (string): Master database password
|
||||
- `ca_certificate` (string): CA certificate for SSL connections
|
||||
|
||||
### Storage Bucket (`buckets.s3.aws.example.io`)
|
||||
- `bucket_name` (string): The S3 bucket name
|
||||
- `region` (string): AWS region where bucket is located
|
||||
- `arn` (string): Full ARN of the S3 bucket
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common issues
|
||||
|
||||
**MRDs not activating:**
|
||||
```bash
|
||||
# Check activation policy exists and matches
|
||||
kubectl get mrap
|
||||
kubectl describe mrap my-policy
|
||||
|
||||
# Verify MRD exists
|
||||
kubectl get mrd my-resource.provider.example.io
|
||||
kubectl describe mrd my-resource.provider.example.io
|
||||
```
|
||||
|
||||
**CRDs not created:**
|
||||
```bash
|
||||
# Check MRD controller logs
|
||||
kubectl logs -n crossplane-system deployment/provider-example
|
||||
|
||||
# Verify RBAC permissions
|
||||
kubectl auth can-i create customresourcedefinitions --as=system:serviceaccount:crossplane-system:provider-example
|
||||
```
|
||||
|
||||
**Resource creation fails:**
|
||||
```bash
|
||||
# Verify MRD is active
|
||||
kubectl get mrd my-resource.provider.example.io -o jsonpath='{.spec.state}'
|
||||
|
||||
# Check if CRD exists
|
||||
kubectl get crd my-resource.provider.example.io
|
||||
|
||||
# Look for controller errors
|
||||
kubectl describe my-resource my-instance
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
### Performance optimization
|
||||
- Start with inactive MRDs for providers with >20 resources
|
||||
- Document recommended activation patterns for common use cases
|
||||
- Provide environment-specific activation policy examples
|
||||
|
||||
### User experience
|
||||
- Include helpful error messages when resources aren't activated
|
||||
- Provide clear migration guides for existing users
|
||||
- Document connection details thoroughly
|
||||
|
||||
### Testing strategy
|
||||
- Test both with and without SafeStart in CI
|
||||
- Verify activation/deactivation cycles work correctly
|
||||
- Test resource creation after activation
|
||||
|
||||
SafeStart provides significant value for large providers and improves the
|
||||
overall Crossplane user experience. Following this guide helps ensure your
|
||||
implementation is robust, well-documented, and user-friendly.
|
||||
|
|
@ -0,0 +1,691 @@
|
|||
---
|
||||
title: Writing MRD Activation Policies
|
||||
weight: 150
|
||||
description: Learn how to create effective activation policies for managed resources
|
||||
---
|
||||
|
||||
ManagedResourceActivationPolicy (MRAP) provides powerful pattern-based control
|
||||
over which Managed Resource Definitions (MRDs) become active in your cluster.
|
||||
This guide shows how to write effective activation policies for different
|
||||
scenarios.
|
||||
|
||||
## Default activation policy
|
||||
|
||||
Crossplane automatically creates a default ManagedResourceActivationPolicy when
|
||||
installed. Understanding and configuring this default policy is crucial for
|
||||
effective MRD management.
|
||||
|
||||
### What is the default MRAP?
|
||||
|
||||
The default MRAP is automatically created by Crossplane and activates managed
|
||||
resources according to configurable patterns. By default, it uses a wildcard
|
||||
pattern that activates **all** managed resources:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: crossplane-default-activation-policy
|
||||
spec:
|
||||
activations:
|
||||
- "*" # Activates all managed resources
|
||||
```
|
||||
|
||||
{{< hint "important" >}}
|
||||
The default `"*"` pattern means SafeStart providers will still create all CRDs,
|
||||
defeating the performance benefits. Most users should customize this behavior.
|
||||
{{< /hint >}}
|
||||
|
||||
### Configuring default activation with Helm
|
||||
|
||||
Configure the default activation policy during Crossplane installation:
|
||||
|
||||
```yaml
|
||||
# values.yaml for Crossplane Helm installation
|
||||
provider:
|
||||
defaultActivations:
|
||||
- "*" # Default: activate everything (not recommended for large providers)
|
||||
```
|
||||
|
||||
**Recommended configurations:**
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "Production (Selective)" >}}
|
||||
```yaml
|
||||
# Recommended: Disable default activation, use targeted policies
|
||||
provider:
|
||||
defaultActivations: null # or []
|
||||
|
||||
# Then create provider-specific MRAPs
|
||||
# This provides better control and performance
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "Development (Permissive)" >}}
|
||||
```yaml
|
||||
# For development environments where you want broad access
|
||||
provider:
|
||||
defaultActivations:
|
||||
- "*.aws.crossplane.io"
|
||||
- "*.gcp.crossplane.io"
|
||||
- "*.azure.crossplane.io"
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "Service-Specific" >}}
|
||||
```yaml
|
||||
# Activate only specific service categories
|
||||
provider:
|
||||
defaultActivations:
|
||||
- "*.rds.aws.crossplane.io" # All RDS resources
|
||||
- "*.s3.aws.crossplane.io" # All S3 resources
|
||||
- "instances.ec2.aws.crossplane.io" # Only EC2 instances
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### Modifying the default policy after installation
|
||||
|
||||
The default activation policy can be modified directly and changes will persist:
|
||||
|
||||
```shell
|
||||
# View current default policy
|
||||
kubectl get mrap crossplane-default-activation-policy -o yaml
|
||||
|
||||
# Permanently modify to disable default activation
|
||||
kubectl patch mrap crossplane-default-activation-policy --type='merge' \
|
||||
-p='{"spec":{"activations":["nonexistent.example.com"]}}'
|
||||
|
||||
# Or remove all activations
|
||||
kubectl patch mrap crossplane-default-activation-policy --type='merge' \
|
||||
-p='{"spec":{"activations":[]}}'
|
||||
|
||||
# Or delete the default policy entirely
|
||||
kubectl delete mrap crossplane-default-activation-policy
|
||||
```
|
||||
|
||||
{{< hint "note" >}}
|
||||
**Changes to the default policy are permanent.** Once the default MRAP exists,
|
||||
Crossplane will not modify it. The Helm chart `provider.defaultActivations`
|
||||
value is only used when creating the policy if it doesn't already exist.
|
||||
{{< /hint >}}
|
||||
|
||||
### Controlling default activation for new installations
|
||||
|
||||
The Helm chart value only affects the **initial creation** of the default policy:
|
||||
|
||||
```shell
|
||||
# This only matters for NEW installations or when the default policy doesn't exist
|
||||
helm upgrade crossplane crossplane-stable/crossplane \
|
||||
--set provider.defaultActivations=null \
|
||||
--namespace crossplane-system --reuse-values
|
||||
```
|
||||
|
||||
If you want to reset the default policy to match new Helm values:
|
||||
|
||||
```shell
|
||||
# Delete existing policy so Crossplane recreates it from Helm values
|
||||
kubectl delete mrap crossplane-default-activation-policy
|
||||
|
||||
# Restart Crossplane to recreate the policy with current Helm values
|
||||
kubectl rollout restart deployment/crossplane -n crossplane-system
|
||||
```
|
||||
|
||||
### Best practices for default activation
|
||||
|
||||
**Recommended approach:**
|
||||
1. **Disable default activation** by setting `provider.defaultActivations: null`
|
||||
2. **Create targeted MRAPs** for each provider or service category
|
||||
3. **Use specific patterns** rather than wildcards when possible
|
||||
|
||||
```shell
|
||||
# 1. Install Crossplane with no default activation
|
||||
helm install crossplane crossplane-stable/crossplane \
|
||||
--set provider.defaultActivations=null
|
||||
|
||||
# 2. Create provider-specific activation policies
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: aws-core-services
|
||||
spec:
|
||||
activations:
|
||||
- "instances.ec2.aws.crossplane.io"
|
||||
- "*.rds.aws.crossplane.io"
|
||||
- "buckets.s3.aws.crossplane.io"
|
||||
EOF
|
||||
```
|
||||
|
||||
**Why this approach is better:**
|
||||
- **Performance**: Only activates resources you actually use
|
||||
- **Security**: Principle of least privilege for resource access
|
||||
- **Clarity**: Explicit about which resources are available
|
||||
- **Maintainability**: Easier to understand and modify activation patterns
|
||||
|
||||
## Policy basics
|
||||
|
||||
Beyond the default policy, you can create custom activation policies that
|
||||
specify which MRDs should be activated using pattern matching:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: my-policy
|
||||
spec:
|
||||
activations:
|
||||
- "exact-match.provider.example.com"
|
||||
- "*.wildcard.example.com"
|
||||
- "prefix-*.example.com"
|
||||
```
|
||||
|
||||
{{< hint "note" >}}
|
||||
Multiple activation policies can exist simultaneously. Their activations are
|
||||
combined, so any MRD matched by any policy becomes active.
|
||||
{{< /hint >}}
|
||||
|
||||
## Activation patterns
|
||||
|
||||
### Exact matching
|
||||
|
||||
Activate specific MRDs by their full name:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
activations:
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- databases.rds.aws.crossplane.io
|
||||
```
|
||||
|
||||
Use exact matching when:
|
||||
* You know exactly which resources you need
|
||||
* You want fine-grained control over individual resources
|
||||
* Security policies require explicit resource approval
|
||||
|
||||
### Wildcard matching
|
||||
|
||||
Use wildcards to activate groups of related resources:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
activations:
|
||||
- "*.rds.aws.crossplane.io" # All RDS resources
|
||||
- "*.storage.gcp.crossplane.io" # All GCP storage resources
|
||||
- "*.compute.azure.crossplane.io" # All Azure compute resources
|
||||
```
|
||||
|
||||
{{< hint "tip" >}}
|
||||
Wildcard patterns only support prefix matching. The `*` must be at the
|
||||
beginning of the pattern and match one or more DNS label components.
|
||||
{{< /hint >}}
|
||||
|
||||
### Provider-wide activation
|
||||
|
||||
Activate all resources from a specific provider:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
activations:
|
||||
- "*.aws.crossplane.io" # All AWS resources
|
||||
- "*.gcp.crossplane.io" # All GCP resources
|
||||
- "*.azure.crossplane.io" # All Azure resources
|
||||
```
|
||||
|
||||
Use provider-wide activation when:
|
||||
* You're migrating from non-SafeStart providers
|
||||
* Your applications use diverse resources from a single provider
|
||||
* Development environments need broad resource access
|
||||
|
||||
## Environment-based policies
|
||||
|
||||
### Development environment
|
||||
|
||||
Activate minimal resources for development:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: development-resources
|
||||
namespace: development
|
||||
spec:
|
||||
activations:
|
||||
# Basic compute
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- "*.compute.gcp.crossplane.io"
|
||||
|
||||
# Storage
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- "*.storage.azure.crossplane.io"
|
||||
|
||||
# Databases
|
||||
- "*.rds.aws.crossplane.io"
|
||||
- instances.sql.gcp.crossplane.io
|
||||
```
|
||||
|
||||
### Staging environment
|
||||
|
||||
Include additional resources for integration testing:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: staging-resources
|
||||
namespace: staging
|
||||
spec:
|
||||
activations:
|
||||
# Everything from development
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- "*.compute.gcp.crossplane.io"
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- "*.storage.azure.crossplane.io"
|
||||
- "*.rds.aws.crossplane.io"
|
||||
- instances.sql.gcp.crossplane.io
|
||||
|
||||
# Additional staging needs
|
||||
- "*.networking.aws.crossplane.io"
|
||||
- "*.iam.aws.crossplane.io"
|
||||
- clusters.eks.aws.crossplane.io
|
||||
- "*.monitoring.gcp.crossplane.io"
|
||||
```
|
||||
|
||||
### Production environment
|
||||
|
||||
Activate all necessary resources:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: production-resources
|
||||
namespace: production
|
||||
spec:
|
||||
activations:
|
||||
# Broad activation for production flexibility
|
||||
- "*.aws.crossplane.io"
|
||||
- "*.gcp.crossplane.io"
|
||||
- "*.azure.crossplane.io"
|
||||
```
|
||||
|
||||
## Service-based policies
|
||||
|
||||
### Database services
|
||||
|
||||
Create policies focused on specific service categories:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: database-services
|
||||
spec:
|
||||
activations:
|
||||
# Relational databases
|
||||
- "*.rds.aws.crossplane.io"
|
||||
- instances.sql.gcp.crossplane.io
|
||||
- servers.postgresql.azure.crossplane.io
|
||||
- servers.mysql.azure.crossplane.io
|
||||
|
||||
# NoSQL databases
|
||||
- tables.dynamodb.aws.crossplane.io
|
||||
- instances.spanner.gcp.crossplane.io
|
||||
- accounts.cosmosdb.azure.crossplane.io
|
||||
|
||||
# Caching
|
||||
- clusters.elasticache.aws.crossplane.io
|
||||
- instances.memorystore.gcp.crossplane.io
|
||||
- caches.redis.azure.crossplane.io
|
||||
```
|
||||
|
||||
### Networking services
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: networking-services
|
||||
spec:
|
||||
activations:
|
||||
# Core networking
|
||||
- vpcs.ec2.aws.crossplane.io
|
||||
- subnets.ec2.aws.crossplane.io
|
||||
- networks.compute.gcp.crossplane.io
|
||||
- subnetworks.compute.gcp.crossplane.io
|
||||
- virtualnetworks.network.azure.crossplane.io
|
||||
|
||||
# Load balancing
|
||||
- "*.elbv2.aws.crossplane.io"
|
||||
- "*.compute.gcp.crossplane.io"
|
||||
- loadbalancers.network.azure.crossplane.io
|
||||
|
||||
# DNS and routing
|
||||
- "*.route53.aws.crossplane.io"
|
||||
- "*.dns.gcp.crossplane.io"
|
||||
- zones.dns.azure.crossplane.io
|
||||
```
|
||||
|
||||
## Team-based policies
|
||||
|
||||
### Platform team
|
||||
|
||||
Broad access for platform engineering:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: platform-team-resources
|
||||
spec:
|
||||
activations:
|
||||
# Infrastructure management
|
||||
- "*.iam.aws.crossplane.io"
|
||||
- "*.iam.gcp.crossplane.io"
|
||||
- "*.authorization.azure.crossplane.io"
|
||||
|
||||
# Networking and security
|
||||
- "*.ec2.aws.crossplane.io"
|
||||
- "*.compute.gcp.crossplane.io"
|
||||
- "*.network.azure.crossplane.io"
|
||||
|
||||
# Monitoring and logging
|
||||
- "*.cloudwatch.aws.crossplane.io"
|
||||
- "*.monitoring.gcp.crossplane.io"
|
||||
- "*.insights.azure.crossplane.io"
|
||||
```
|
||||
|
||||
### Application team
|
||||
|
||||
Resources needed by application developers:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: app-team-resources
|
||||
spec:
|
||||
activations:
|
||||
# Compute resources
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- clusters.eks.aws.crossplane.io
|
||||
- clusters.gke.gcp.crossplane.io
|
||||
|
||||
# Storage
|
||||
- buckets.s3.aws.crossplane.io
|
||||
- buckets.storage.gcp.crossplane.io
|
||||
- accounts.storage.azure.crossplane.io
|
||||
|
||||
# Databases (read-only access through compositions)
|
||||
- "*.rds.aws.crossplane.io"
|
||||
- instances.sql.gcp.crossplane.io
|
||||
```
|
||||
|
||||
## Dynamic activation patterns
|
||||
|
||||
### Conditional activation
|
||||
|
||||
Use multiple policies to create conditional resource activation:
|
||||
|
||||
```yaml
|
||||
# Base resources always active
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: base-resources
|
||||
spec:
|
||||
activations:
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- buckets.s3.aws.crossplane.io
|
||||
|
||||
---
|
||||
# Optional resources for advanced features
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: advanced-resources
|
||||
spec:
|
||||
activations:
|
||||
- clusters.eks.aws.crossplane.io
|
||||
- "*.lambda.aws.crossplane.io"
|
||||
```
|
||||
|
||||
You can delete the `advanced-resources` policy to quickly deactivate optional
|
||||
resources while keeping base functionality.
|
||||
|
||||
### Feature flag patterns
|
||||
|
||||
Use labels and naming to create feature flag-like behavior:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: feature-ml-services
|
||||
labels:
|
||||
feature: machine-learning
|
||||
environment: production
|
||||
spec:
|
||||
activations:
|
||||
- "*.sagemaker.aws.crossplane.io"
|
||||
- "*.ml.gcp.crossplane.io"
|
||||
- "*.cognitiveservices.azure.crossplane.io"
|
||||
```
|
||||
|
||||
## Validation and testing
|
||||
|
||||
### Check activation status
|
||||
|
||||
Verify your policies are working correctly:
|
||||
|
||||
```shell
|
||||
# List all activation policies
|
||||
kubectl get mrap
|
||||
|
||||
# Check specific policy status
|
||||
kubectl describe mrap my-policy
|
||||
|
||||
# See which MRDs are currently active
|
||||
kubectl get mrds --field-selector spec.state=Active
|
||||
|
||||
# Count active MRDs by provider
|
||||
kubectl get mrds -l crossplane.io/provider=provider-aws --field-selector spec.state=Active | wc -l
|
||||
```
|
||||
|
||||
### Test resource creation
|
||||
|
||||
Verify activated resources work correctly:
|
||||
|
||||
```shell
|
||||
# Try creating a managed resource
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: s3.aws.crossplane.io/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: test-activation
|
||||
spec:
|
||||
forProvider:
|
||||
region: us-east-1
|
||||
EOF
|
||||
|
||||
# Check if the resource was created successfully
|
||||
kubectl get bucket test-activation
|
||||
kubectl describe bucket test-activation
|
||||
```
|
||||
|
||||
### Policy debugging
|
||||
|
||||
Common issues and solutions:
|
||||
|
||||
```shell
|
||||
# Check if MRD exists but isn't active
|
||||
kubectl get mrd my-resource.provider.example.com
|
||||
kubectl describe mrd my-resource.provider.example.com
|
||||
|
||||
# Verify policy is matching correctly
|
||||
kubectl get mrap my-policy -o yaml | grep -A20 status
|
||||
|
||||
# Look for controller errors
|
||||
kubectl logs -n crossplane-system deployment/crossplane | grep -i mrd
|
||||
```
|
||||
|
||||
## Performance considerations
|
||||
|
||||
### Activation overhead
|
||||
|
||||
Each activation creates a CRD, which has resource overhead:
|
||||
|
||||
```yaml
|
||||
# Efficient - activates exactly what's needed
|
||||
spec:
|
||||
activations:
|
||||
- instances.ec2.aws.crossplane.io
|
||||
- buckets.s3.aws.crossplane.io
|
||||
|
||||
# Less efficient - activates everything
|
||||
spec:
|
||||
activations:
|
||||
- "*.aws.crossplane.io" # Could be 200+ resources
|
||||
```
|
||||
|
||||
### Policy consolidation
|
||||
|
||||
Multiple small policies vs. few large policies:
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab "Multiple Small Policies (Recommended)" >}}
|
||||
```yaml
|
||||
# Easier to manage and understand
|
||||
---
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: compute-resources
|
||||
spec:
|
||||
activations:
|
||||
- "*.ec2.aws.crossplane.io"
|
||||
- "*.compute.gcp.crossplane.io"
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: storage-resources
|
||||
spec:
|
||||
activations:
|
||||
- "*.s3.aws.crossplane.io"
|
||||
- "*.storage.gcp.crossplane.io"
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab "Single Large Policy" >}}
|
||||
```yaml
|
||||
# Harder to manage but fewer resources
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: all-resources
|
||||
spec:
|
||||
activations:
|
||||
- "*.ec2.aws.crossplane.io"
|
||||
- "*.compute.gcp.crossplane.io"
|
||||
- "*.s3.aws.crossplane.io"
|
||||
- "*.storage.gcp.crossplane.io"
|
||||
# ... many more activations
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
## Policy lifecycle management
|
||||
|
||||
### GitOps workflow
|
||||
|
||||
Store activation policies in Git for proper change management:
|
||||
|
||||
```yaml
|
||||
# clusters/production/activation-policies/
|
||||
production-compute.yaml
|
||||
production-storage.yaml
|
||||
production-networking.yaml
|
||||
|
||||
# clusters/staging/activation-policies/
|
||||
staging-core.yaml
|
||||
staging-experimental.yaml
|
||||
|
||||
# clusters/development/activation-policies/
|
||||
development-minimal.yaml
|
||||
```
|
||||
|
||||
### Versioning strategies
|
||||
|
||||
Use metadata to track policy versions:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: production-resources
|
||||
labels:
|
||||
version: "v2.1.0"
|
||||
environment: production
|
||||
team: platform-engineering
|
||||
annotations:
|
||||
policy.crossplane.io/description: "Production resource activation policy"
|
||||
policy.crossplane.io/last-updated: "2024-01-15"
|
||||
policy.crossplane.io/approved-by: "platform-team"
|
||||
spec:
|
||||
activations:
|
||||
- "*.aws.crossplane.io"
|
||||
```
|
||||
|
||||
## Integration with compositions
|
||||
|
||||
### Composition compatibility
|
||||
|
||||
Compositions work with both active and inactive MRDs, but resource creation
|
||||
only succeeds when MRDs are active:
|
||||
|
||||
```yaml
|
||||
# This composition can exist regardless of MRD state
|
||||
apiVersion: apiextensions.crossplane.io/v1
|
||||
kind: Composition
|
||||
metadata:
|
||||
name: webapp-stack
|
||||
spec:
|
||||
compositeTypeRef:
|
||||
apiVersion: platform.example.com/v1alpha1
|
||||
kind: WebApp
|
||||
resources:
|
||||
- name: database
|
||||
base:
|
||||
apiVersion: rds.aws.crossplane.io/v1alpha1
|
||||
kind: DBInstance
|
||||
# This only works if RDS MRDs are active
|
||||
- name: storage
|
||||
base:
|
||||
apiVersion: s3.aws.crossplane.io/v1alpha1
|
||||
kind: Bucket
|
||||
# This only works if S3 MRDs are active
|
||||
```
|
||||
|
||||
### Activation dependencies
|
||||
|
||||
Document activation requirements in compositions:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1
|
||||
kind: Composition
|
||||
metadata:
|
||||
name: ml-pipeline
|
||||
annotations:
|
||||
composition.crossplane.io/required-mrds: |
|
||||
- "*.sagemaker.aws.crossplane.io"
|
||||
- "*.s3.aws.crossplane.io"
|
||||
- "*.iam.aws.crossplane.io"
|
||||
spec:
|
||||
# ... composition definition
|
||||
```
|
||||
|
||||
This helps operators understand which activation policies are needed for
|
||||
specific compositions to work correctly.
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
---
|
||||
title: Managed Resource Definitions
|
||||
weight: 10
|
||||
description: Understand Managed Resource Definitions (MRDs) and selective resource activation
|
||||
---
|
||||
|
||||
Managed Resource Definitions (MRDs) provide a lightweight abstraction over
|
||||
Kubernetes Custom Resource Definitions (CRDs) that enables selective
|
||||
installation and better documentation of managed resources.
|
||||
|
||||
{{< hint "note" >}}
|
||||
MRDs are available in Crossplane v2.0+ as an alpha feature.
|
||||
{{< /hint >}}
|
||||
|
||||
## What are managed resource definitions?
|
||||
|
||||
A Managed Resource Definition (MRD) is essentially a CRD with additional
|
||||
metadata that provides:
|
||||
|
||||
* **Connection details schema** - Documents what connection details the
|
||||
managed resource provides
|
||||
* **Activation control** - Controls whether the underlying CRD gets installed
|
||||
in your cluster
|
||||
* **Resource discovery** - Makes it easier to understand what resources are
|
||||
available
|
||||
|
||||
**Every managed resource in a provider package has an associated MRD.** The MRD
|
||||
contains the same schema as the CRD, plus additional Crossplane-specific
|
||||
metadata.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
provider(Provider Package)
|
||||
mrd(MRD)
|
||||
crd(CRD)
|
||||
mr(Managed Resource)
|
||||
|
||||
provider --> mrd
|
||||
mrd --"when active"--> crd
|
||||
crd --> mr
|
||||
|
||||
style mrd fill:#e1f5fe
|
||||
style crd fill:#f3e5f5
|
||||
```
|
||||
|
||||
## Why use managed resource definitions?
|
||||
|
||||
MRDs solve several challenges with traditional provider packages:
|
||||
|
||||
### Performance optimization
|
||||
Installing a provider creates CRDs for _every_ managed resource the provider
|
||||
supports. For large providers like AWS, this can mean hundreds of CRDs that
|
||||
you may never use.
|
||||
|
||||
**MRDs let you install only the CRDs you need**, reducing Kubernetes API
|
||||
server overhead and improving cluster performance.
|
||||
|
||||
### Connection details discovery
|
||||
Understanding what connection details a managed resource provides requires
|
||||
reading provider source code or trial-and-error testing.
|
||||
|
||||
**MRDs document connection details in the schema**, making it clear what
|
||||
credentials and endpoints each resource provides.
|
||||
|
||||
### Selective installation
|
||||
Different environments may need different subsets of managed resources. A
|
||||
development environment might only need basic resources, while production
|
||||
needs the full set.
|
||||
|
||||
**MRDs enable environment-specific resource activation** through policies.
|
||||
|
||||
## How MRDs work
|
||||
|
||||
When you install a provider package, Crossplane creates:
|
||||
|
||||
1. **MRDs for all resources** - Every managed resource gets an MRD
|
||||
2. **CRDs only when activated** - Crossplane creates CRDs only for active MRDs
|
||||
3. **Activation policies** - ManagedResourceActivationPolicy controls which
|
||||
MRDs become active
|
||||
|
||||
### MRD lifecycle
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
install[Install Provider]
|
||||
createMRD[Create MRDs]
|
||||
checkPolicy{Activation Policy<br/>Matches?}
|
||||
activate[Activate MRD]
|
||||
createCRD[Create CRD]
|
||||
inactive[MRD Inactive]
|
||||
|
||||
install --> createMRD
|
||||
createMRD --> checkPolicy
|
||||
checkPolicy -->|Yes| activate
|
||||
checkPolicy -->|No| inactive
|
||||
activate --> createCRD
|
||||
|
||||
style activate fill:#c8e6c9
|
||||
style inactive fill:#ffcdd2
|
||||
```
|
||||
|
||||
### MRD states
|
||||
|
||||
MRDs can be in one of two states:
|
||||
|
||||
* **Active** - The underlying CRD exists and you can create managed resources
|
||||
* **Inactive** - No CRD exists, managed resource creation fails
|
||||
|
||||
You can change an MRD's state by:
|
||||
* Editing the MRD directly (`spec.state: Active`)
|
||||
* Using a ManagedResourceActivationPolicy
|
||||
* Provider package capabilities (SafeStart)
|
||||
|
||||
## Connection details schema
|
||||
|
||||
MRDs document the connection details that managed resources provide. This makes
|
||||
it easier to understand what credentials and endpoints you get when creating
|
||||
resources.
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceDefinition
|
||||
metadata:
|
||||
name: instances.ec2.aws.crossplane.io
|
||||
spec:
|
||||
connectionDetails:
|
||||
- name: endpoint
|
||||
description: The connection endpoint for the database
|
||||
type: string
|
||||
- name: port
|
||||
description: The port number for connections
|
||||
type: integer
|
||||
- name: username
|
||||
description: The master username for the database
|
||||
type: string
|
||||
- name: password
|
||||
description: The master password for the database
|
||||
type: string
|
||||
fromConnectionSecretKey: password
|
||||
```
|
||||
|
||||
The `connectionDetails` field documents:
|
||||
* **Connection detail names** - What keys appear in connection secrets
|
||||
* **Descriptions** - What each connection detail contains
|
||||
* **Types** - The data type of each detail
|
||||
* **Source keys** - How details map from provider responses
|
||||
|
||||
## Managed Resource Activation Policy
|
||||
|
||||
ManagedResourceActivationPolicy (MRAP) provides pattern-based control over
|
||||
which MRDs become active. This is more scalable than manually activating
|
||||
individual MRDs.
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: aws-core-resources
|
||||
spec:
|
||||
activations:
|
||||
- "instances.ec2.aws.crossplane.io" # Specific MRD
|
||||
- "*.rds.aws.crossplane.io" # All RDS resources
|
||||
- "buckets.s3.aws.crossplane.io" # S3 buckets
|
||||
```
|
||||
|
||||
### Activation patterns
|
||||
|
||||
MRAP supports several activation patterns:
|
||||
|
||||
* **Exact match**: `instances.ec2.aws.crossplane.io`
|
||||
* **Wildcard prefix**: `*.rds.aws.crossplane.io` (all RDS resources)
|
||||
* **Provider wildcard**: `*.aws.crossplane.io` (all AWS resources)
|
||||
|
||||
Multiple MRAPs can exist, and their activations are combined.
|
||||
|
||||
## Provider capabilities
|
||||
|
||||
Providers can declare capabilities that affect MRD behavior:
|
||||
|
||||
### SafeStart capability
|
||||
Providers with the `SafeStart` capability start with all MRDs inactive by
|
||||
default. This prevents performance issues when installing large providers.
|
||||
|
||||
Without SafeStart, all MRDs are active by default for backward compatibility.
|
||||
|
||||
```yaml
|
||||
# In provider package metadata
|
||||
spec:
|
||||
capabilities:
|
||||
- name: SafeStart
|
||||
```
|
||||
|
||||
{{< hint "note" >}}
|
||||
Implementing SafeStart requires significant provider code changes. Provider
|
||||
developers should follow the
|
||||
[SafeStart implementation guide]({{< ref "../guides/implementing-safestart" >}})
|
||||
for detailed technical requirements and examples.
|
||||
{{< /hint >}}
|
||||
|
||||
### SafeStart implementation examples
|
||||
|
||||
The Crossplane community has implemented SafeStart in several providers:
|
||||
|
||||
* **provider-nop** - [Reference implementation](https://github.com/crossplane-contrib/provider-nop/pull/24)
|
||||
showing SafeStart integration with both namespaced and cluster-scoped resources
|
||||
* **provider-aws** - Large provider demonstrating SafeStart performance benefits
|
||||
|
||||
These implementations provide real-world examples of:
|
||||
- MRD controller integration
|
||||
- Build process modifications
|
||||
- Testing strategies for SafeStart behavior
|
||||
- Migration approaches for existing users
|
||||
|
||||
## Key concepts
|
||||
|
||||
Understanding these terms helps when working with MRDs:
|
||||
|
||||
* **MRD** - The definition that may or may not have an active CRD
|
||||
* **MRAP** - Policy that controls which MRDs become active
|
||||
* **Active state** - MRD has an underlying CRD, resources can be created
|
||||
* **Inactive state** - No CRD exists, resource creation fails
|
||||
* **SafeStart** - Provider capability that defaults MRDs to inactive
|
||||
* **Connection details schema** - Documentation of what connection details
|
||||
a managed resource provides
|
||||
|
||||
## Relationship to other Crossplane features
|
||||
|
||||
MRDs integrate with existing Crossplane concepts:
|
||||
|
||||
* **Providers** - Create MRDs when installed
|
||||
* **Managed resources** - Can only be created when their MRD is active
|
||||
* **Compositions** - Can reference both active and inactive managed resources
|
||||
(composition validation occurs at render time)
|
||||
* **Claims** - Work normally once the underlying managed resources are active
|
||||
|
||||
MRDs are backward compatible. Existing providers and compositions continue to
|
||||
work without modification.
|
||||
|
|
@ -0,0 +1,372 @@
|
|||
---
|
||||
title: Provider Capabilities
|
||||
weight: 20
|
||||
description: Understand provider capabilities and how they affect resource behavior
|
||||
---
|
||||
|
||||
Provider capabilities are declarative features that providers can implement to
|
||||
modify their behavior and integration with Crossplane. Capabilities enable
|
||||
providers to opt into new features while maintaining backward compatibility.
|
||||
|
||||
## What are provider capabilities?
|
||||
|
||||
Provider capabilities are metadata declarations in provider packages that tell
|
||||
Crossplane how the provider should behave. They're similar to feature flags
|
||||
but are declared at the package level.
|
||||
|
||||
```yaml
|
||||
# In provider package metadata
|
||||
apiVersion: meta.pkg.crossplane.io/v1alpha1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: provider-aws
|
||||
spec:
|
||||
capabilities:
|
||||
- name: SafeStart
|
||||
- name: CustomCapability
|
||||
```
|
||||
|
||||
Crossplane reads these capabilities and modifies its behavior when installing
|
||||
and managing the provider.
|
||||
|
||||
## Available capabilities
|
||||
|
||||
### SafeStart
|
||||
|
||||
The `SafeStart` capability changes how Managed Resource Definitions (MRDs) are
|
||||
activated when the provider is installed.
|
||||
|
||||
**Without SafeStart:**
|
||||
- All MRDs are automatically activated
|
||||
- All corresponding CRDs are created immediately
|
||||
- Compatible with legacy providers and existing workflows
|
||||
|
||||
**With SafeStart:**
|
||||
- All MRDs start in `Inactive` state
|
||||
- No CRDs are created until MRDs are explicitly activated
|
||||
- Reduces initial resource overhead and improves performance
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
capabilities:
|
||||
- name: SafeStart
|
||||
```
|
||||
|
||||
{{< hint "tip" >}}
|
||||
SafeStart is particularly valuable for large providers like AWS that define
|
||||
hundreds of managed resources. It prevents performance issues by avoiding the
|
||||
creation of unused CRDs.
|
||||
{{< /hint >}}
|
||||
|
||||
#### When to use SafeStart
|
||||
|
||||
Use SafeStart when:
|
||||
* Your provider defines many managed resources (>50)
|
||||
* Users typically need only a subset of available resources
|
||||
* Installation performance and resource usage are concerns
|
||||
* You want to provide better resource discovery through MRDs
|
||||
|
||||
Don't use SafeStart when:
|
||||
* Your provider has few managed resources (<20)
|
||||
* Most users need all available resources
|
||||
* Backward compatibility with existing installations is critical
|
||||
* Your users aren't ready to manage resource activation
|
||||
|
||||
## Capability matching
|
||||
|
||||
Crossplane supports flexible matching for capability names:
|
||||
|
||||
* **Exact match**: `SafeStart`
|
||||
* **Case variations**: `safestart`, `safe-start`, `SafeStart`
|
||||
* **Fuzzy matching**: Handles common spelling variations
|
||||
|
||||
This flexibility prevents issues when providers use different naming conventions.
|
||||
|
||||
## How capabilities affect installation
|
||||
|
||||
The provider installation process changes based on declared capabilities:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
install[Install Provider Package]
|
||||
readCaps[Read Capabilities]
|
||||
checkSafe{Has SafeStart?}
|
||||
activateAll[Activate All MRDs]
|
||||
keepInactive[Keep MRDs Inactive]
|
||||
createCRDs[Create All CRDs]
|
||||
waitPolicy[Wait for Activation Policy]
|
||||
|
||||
install --> readCaps
|
||||
readCaps --> checkSafe
|
||||
checkSafe -->|No| activateAll
|
||||
checkSafe -->|Yes| keepInactive
|
||||
activateAll --> createCRDs
|
||||
keepInactive --> waitPolicy
|
||||
|
||||
style keepInactive fill:#c8e6c9
|
||||
style waitPolicy fill:#fff3e0
|
||||
```
|
||||
|
||||
## Provider compatibility
|
||||
|
||||
### Legacy providers
|
||||
|
||||
Providers without any capabilities work exactly as before:
|
||||
* All MRDs are active by default
|
||||
* All CRDs are created immediately
|
||||
* No changes required for existing compositions or configurations
|
||||
|
||||
### Modern providers
|
||||
|
||||
Providers with SafeStart capability require additional setup:
|
||||
* Create ManagedResourceActivationPolicy to activate needed resources
|
||||
* Verify required CRDs exist before creating managed resources
|
||||
* Use MRD connection details documentation for resource planning
|
||||
|
||||
## Implementing SafeStart in providers
|
||||
|
||||
SafeStart implementation requires several technical changes to provider code and
|
||||
build processes. This section provides an overview - see the
|
||||
[complete SafeStart implementation guide]({{< ref "../guides/implementing-safestart" >}})
|
||||
for detailed instructions.
|
||||
|
||||
### Key implementation requirements
|
||||
|
||||
**Code changes:**
|
||||
- Add MRD controller logic to handle activation/deactivation
|
||||
- Support both namespaced and cluster-scoped resources
|
||||
- Generate MRDs with connection details documentation
|
||||
- Implement CRD lifecycle management
|
||||
|
||||
**Build process changes:**
|
||||
- Update Makefile to generate MRDs alongside CRDs
|
||||
- Modify CI/CD to test SafeStart behavior
|
||||
- Include MRDs in provider package artifacts
|
||||
|
||||
**RBAC updates:**
|
||||
SafeStart providers need additional permissions to manage CRDs dynamically:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: my-provider-system
|
||||
rules:
|
||||
# Standard provider permissions
|
||||
- apiGroups: [""]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "update", "patch"]
|
||||
|
||||
# Additional SafeStart permissions
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["apiextensions.crossplane.io"]
|
||||
resources: ["managedresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch", "update", "patch"]
|
||||
```
|
||||
|
||||
### Provider package metadata
|
||||
|
||||
Declare SafeStart capability in your provider package:
|
||||
|
||||
```yaml
|
||||
apiVersion: meta.pkg.crossplane.io/v1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: my-provider
|
||||
spec:
|
||||
package: registry.example.com/my-provider:v2.0.0
|
||||
capabilities:
|
||||
- name: SafeStart
|
||||
```
|
||||
|
||||
### MRD generation with connection details
|
||||
|
||||
Generate MRDs that document connection details for better user experience:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceDefinition
|
||||
metadata:
|
||||
name: databases.rds.aws.example.io
|
||||
spec:
|
||||
group: rds.aws.example.io
|
||||
names:
|
||||
kind: Database
|
||||
plural: databases
|
||||
scope: Namespaced
|
||||
|
||||
# Connection details documentation
|
||||
connectionDetails:
|
||||
- name: endpoint
|
||||
description: "The RDS instance connection endpoint"
|
||||
type: string
|
||||
fromConnectionSecretKey: endpoint
|
||||
- name: port
|
||||
description: "The port number for database connections"
|
||||
type: integer
|
||||
fromConnectionSecretKey: port
|
||||
- name: username
|
||||
description: "The master username for the database"
|
||||
type: string
|
||||
fromConnectionSecretKey: username
|
||||
- name: password
|
||||
description: "The master password for the database"
|
||||
type: string
|
||||
fromConnectionSecretKey: password
|
||||
```
|
||||
|
||||
### Implementation examples
|
||||
|
||||
The [provider-nop SafeStart implementation](https://github.com/crossplane-contrib/provider-nop/pull/24)
|
||||
demonstrates:
|
||||
- Adding both namespaced and cluster-scoped resource variants
|
||||
- MRD controller integration
|
||||
- Build process updates for SafeStart support
|
||||
- Testing strategies for SafeStart behavior
|
||||
|
||||
{{< hint "tip" >}}
|
||||
See the [complete SafeStart implementation guide]({{< ref "../guides/implementing-safestart" >}})
|
||||
for step-by-step instructions, code examples, and testing strategies.
|
||||
{{< /hint >}}
|
||||
|
||||
### Migration considerations
|
||||
|
||||
When adding SafeStart to existing providers:
|
||||
|
||||
**Backward compatibility:**
|
||||
- Existing provider installations continue working unchanged
|
||||
- New installations start with inactive MRDs
|
||||
- Provide migration documentation for users
|
||||
|
||||
**Version strategy:**
|
||||
```yaml
|
||||
# Document version compatibility clearly
|
||||
# Provider v1.x: Traditional CRD installation
|
||||
# Provider v2.0+: SafeStart support with MRDs
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
### For provider developers
|
||||
|
||||
**Do use SafeStart when:**
|
||||
* Your provider has >50 managed resources
|
||||
* Resource activation patterns vary by environment
|
||||
* Performance optimization is important
|
||||
|
||||
**Document capabilities clearly:**
|
||||
* Explain what each capability does
|
||||
* Provide migration guides for existing users
|
||||
* Include examples of activation policies
|
||||
|
||||
**Test compatibility:**
|
||||
* Verify behavior with and without capabilities
|
||||
* Test with different Crossplane versions
|
||||
* Validate RBAC permissions
|
||||
|
||||
### For platform operators
|
||||
|
||||
**Plan activation policies:**
|
||||
```yaml
|
||||
# Development environment - minimal resources
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: dev-resources
|
||||
spec:
|
||||
activations:
|
||||
- "databases.*.example.com"
|
||||
- "buckets.*.example.com"
|
||||
|
||||
---
|
||||
# Production environment - comprehensive resources
|
||||
apiVersion: apiextensions.crossplane.io/v1alpha1
|
||||
kind: ManagedResourceActivationPolicy
|
||||
metadata:
|
||||
name: prod-resources
|
||||
spec:
|
||||
activations:
|
||||
- "*.example.com" # Activate all resources
|
||||
```
|
||||
|
||||
**Monitor activation status:**
|
||||
```shell
|
||||
# Check which MRDs are active
|
||||
kubectl get mrds -l provider=my-provider
|
||||
|
||||
# Verify activation policies
|
||||
kubectl get mrap -o wide
|
||||
|
||||
# Monitor resource usage
|
||||
kubectl top nodes
|
||||
```
|
||||
|
||||
## Future capabilities
|
||||
|
||||
The capability system is extensible. Future capabilities might include:
|
||||
|
||||
* **ResourceQuotas** - Automatic resource limit management
|
||||
* **NetworkPolicies** - Provider-specific network isolation
|
||||
* **CustomValidation** - Enhanced resource validation
|
||||
* **TelemetryOpt** - Telemetry and observability features
|
||||
|
||||
## Troubleshooting capabilities
|
||||
|
||||
### Common issues
|
||||
|
||||
**MRDs not activating:**
|
||||
```shell
|
||||
# Check if provider has SafeStart capability
|
||||
kubectl get provider my-provider -o yaml | grep -A5 capabilities
|
||||
|
||||
# Verify activation policy exists and matches
|
||||
kubectl get mrap
|
||||
kubectl describe mrap my-policy
|
||||
```
|
||||
|
||||
**CRDs not created:**
|
||||
```shell
|
||||
# Check MRD activation status
|
||||
kubectl get mrd my-resource.example.com
|
||||
|
||||
# Look for controller errors
|
||||
kubectl logs -n crossplane-system deployment/crossplane
|
||||
```
|
||||
|
||||
**Provider installation fails:**
|
||||
```shell
|
||||
# Check provider conditions
|
||||
kubectl describe provider my-provider
|
||||
|
||||
# Look for RBAC issues
|
||||
kubectl get events --field-selector reason=FailedCreate
|
||||
```
|
||||
|
||||
### Debug commands
|
||||
|
||||
```shell
|
||||
# List all providers and their capabilities
|
||||
kubectl get providers -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.capabilities[*].name}{"\n"}{end}'
|
||||
|
||||
# Check MRD activation across providers
|
||||
kubectl get mrds --show-labels
|
||||
|
||||
# Verify CRD creation matches activation
|
||||
kubectl get crds | grep example.com | wc -l
|
||||
kubectl get mrds -l state=Active | wc -l
|
||||
```
|
||||
|
||||
## Relationship to other features
|
||||
|
||||
Provider capabilities integrate with:
|
||||
|
||||
* **MRDs** - SafeStart controls default activation state
|
||||
* **Activation policies** - Work together to control resource availability
|
||||
* **Package manager** - Capabilities are read during package installation
|
||||
* **RBAC** - Some capabilities require additional permissions
|
||||
* **Compositions** - May need updates when capabilities change resource availability
|
||||
|
||||
Capabilities provide a foundation for evolving provider behavior while
|
||||
maintaining compatibility with existing Crossplane installations.
|
||||
|
|
@ -6,12 +6,13 @@ description: Learn what's new in the Crossplane v2 preview
|
|||
**Crossplane v2 makes Crossplane more useful, more intuitive, and less
|
||||
opinionated.**
|
||||
|
||||
Crossplane v2 makes four major changes:
|
||||
Crossplane v2 makes five major changes:
|
||||
|
||||
* **Composite resources are now namespaced**
|
||||
* **Managed resources are now namespaced**
|
||||
* **Managed resources are now namespaced**
|
||||
* **Composition supports any Kubernetes resource**
|
||||
* **Operations enable operational workflows**
|
||||
* **Managed Resource Definitions provide selective resource activation**
|
||||
|
||||
**Crossplane v2 is better suited to building control planes for applications,
|
||||
not just infrastructure.** It removes the need for awkward abstractions like
|
||||
|
|
@ -172,6 +173,61 @@ deprecate and remove cluster scoped MRs at a future date.
|
|||
Read more about Crossplane v2's [backward compatibility](#backward-compatibility).
|
||||
{{</hint>}}
|
||||
|
||||
## Managed Resource Definitions
|
||||
|
||||
Crossplane v2 introduces Managed Resource Definitions (MRDs) that provide
|
||||
selective resource activation and improved resource discovery.
|
||||
|
||||
**MRDs solve performance and usability challenges with large providers.**
|
||||
Installing a provider like AWS traditionally creates hundreds of CRDs, even if
|
||||
you only need a few resources. MRDs let you activate only the resources you
|
||||
actually use.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
provider(Provider Package)
|
||||
mrd1(S3 Bucket MRD)
|
||||
mrd2(EC2 Instance MRD)
|
||||
mrd3(RDS DB MRD)
|
||||
crd1(S3 Bucket CRD)
|
||||
crd2(EC2 Instance CRD)
|
||||
policy(Activation Policy)
|
||||
|
||||
provider --> mrd1
|
||||
provider --> mrd2
|
||||
provider --> mrd3
|
||||
|
||||
policy -.->|activates| mrd1
|
||||
policy -.->|activates| mrd2
|
||||
mrd3 -.->|inactive|
|
||||
|
||||
mrd1 --> crd1
|
||||
mrd2 --> crd2
|
||||
|
||||
style mrd1 fill:#c8e6c9
|
||||
style mrd2 fill:#c8e6c9
|
||||
style mrd3 fill:#ffcdd2
|
||||
style crd1 fill:#e8f5e8
|
||||
style crd2 fill:#e8f5e8
|
||||
```
|
||||
|
||||
### Key MRD benefits
|
||||
|
||||
**Performance optimization** - Only create CRDs for resources you need, reducing
|
||||
cluster overhead and improving provider installation speed.
|
||||
|
||||
**Connection details discovery** - MRDs document what connection details each
|
||||
managed resource provides, making it easier to understand resource capabilities.
|
||||
|
||||
**Policy-based activation** - Use ManagedResourceActivationPolicy (MRAP) to
|
||||
activate resources with flexible pattern matching.
|
||||
|
||||
**SafeStart providers** - Providers can opt into SafeStart capability, starting
|
||||
with all MRDs inactive for better performance.
|
||||
|
||||
Learn more about [Managed Resource Definitions]({{<ref "../managed-resources/managed-resource-definitions">}})
|
||||
and [get started with MRDs]({{<ref "../get-started/get-started-with-mrds">}}).
|
||||
|
||||
## Compose any resource
|
||||
|
||||
Crossplane v2 isn't opinionated about using composition together with managed
|
||||
|
|
|
|||
|
|
@ -61,7 +61,15 @@ initProvider
|
|||
KCL
|
||||
LateInitialize
|
||||
managementPolicies
|
||||
ManagedResourceActivationPolicy
|
||||
ManagedResourceDefinition
|
||||
ManagedResourceDefinitions
|
||||
MRAP
|
||||
MRAPs
|
||||
MR
|
||||
MRD
|
||||
MRD's
|
||||
MRDs
|
||||
MRs
|
||||
Operation-specific
|
||||
PatchSet
|
||||
|
|
@ -71,6 +79,8 @@ ProviderConfigs
|
|||
ProviderRevision
|
||||
RunFunctionRequest
|
||||
RunFunctionResponse
|
||||
SafeStart
|
||||
SafeStart-capable
|
||||
Sigstore
|
||||
SSL
|
||||
StoreConfig
|
||||
|
|
|
|||
|
|
@ -84,3 +84,24 @@ v2
|
|||
validators
|
||||
version-specific
|
||||
webhook-based
|
||||
well-documented
|
||||
user-friendly
|
||||
provider-nop
|
||||
provider-specific
|
||||
pattern-based
|
||||
fine-grained
|
||||
environment-specific
|
||||
real-world
|
||||
trial-and-error
|
||||
CRD-only
|
||||
flag-like
|
||||
Team-based
|
||||
Service-based
|
||||
Provider-wide
|
||||
Environment-based
|
||||
Policy-based
|
||||
Crossplane-specific
|
||||
non-SafeStart
|
||||
GitOps
|
||||
Makefile
|
||||
backporting
|
||||
|
|
|
|||
Loading…
Reference in New Issue