Activate only the managed resources Modelplane composes#351
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the getting-started docs to take advantage of Crossplane v2 “SafeStart” behavior by activating only the managed resource kinds that Modelplane’s compositions actually use, reducing installed CRDs and control-plane memory footprint. It adds a ManagedResourceActivationPolicy to prerequisites and configures Crossplane installation to start with no default managed resource activations.
Changes:
- Add a
ManagedResourceActivationPolicyto activate only the composed managed resource kinds (instead of Crossplane’s wildcard defaults). - Update the Crossplane Helm install command to set
provider.defaultActivations=[]. - Lower the documented Docker Desktop memory recommendation from 10GB to 8GB.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| docs/manifests/getting-started/prerequisites.yaml | Adds a ManagedResourceActivationPolicy that enumerates the managed resource kinds Modelplane composes. |
| docs/content/getting-started/installation.md | Adjusts installation instructions to disable default activations and updates the recommended Docker memory limit. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
negz
commented
Jul 16, 2026
bassam
approved these changes
Jul 16, 2026
Modelplane depends on seven cloud provider families whose CRDs total
around 900 on the control plane, but its compositions only ever compose
about 40 managed resource kinds. Crossplane's default activation policy
turns on every one of them ("*"), so a fresh install pays the API-server
and controller memory for ~900 CRDs it never uses. On a kind install this
measured at 12.3 GiB total, 4.4 GiB of it kube-apiserver.
Crossplane v2 converts each provider CRD into an inactive
ManagedResourceDefinition and only creates the CRD once a
ManagedResourceActivationPolicy names it. This adds such a policy to the
getting-started prerequisites, activating exactly the kinds the
compositions compose, and installs Crossplane with an empty default
activation (provider.defaultActivations=[]) so the policy is the only
thing that activates managed resources.
The activation list is the union across all cloud variants; a single-cloud
install activates a subset. ProviderConfig and ClusterProviderConfig kinds
are deliberately absent: Crossplane doesn't convert them to MRDs, so their
CRDs install unconditionally. The same holds for protection.crossplane.io
Usages. Activation is one-way, so this only benefits fresh installs;
switching an existing control plane doesn't deactivate CRDs already live.
Measured on a kind install of v0.1.0-dev.1784158975.g3e46dfb: 107 CRDs
instead of 912, and 7.2 GiB total instead of 12.3 GiB (kube-apiserver
1.3 GiB instead of 4.4 GiB). All 15 providers stayed healthy. The lighter
footprint drops the guide's Docker memory floor from 10 GiB to 8 GiB.
Towards modelplaneai#334.
Signed-off-by: Nic Cope <nicc@rk0n.org>
The activation policy first landed in the getting-started prerequisites, a manifest users apply by hand. That decoupled it from the Configuration: an operator could pair a Configuration that composes a new managed resource kind with an older policy that doesn't activate it, and nothing would tie the two versions together. crossplane project build collects a ManagedResourceActivationPolicy found under apis/ into the Configuration package, the same as an XRD or Composition, and the package manager establishes it on install. Moving the policy into apis/mrap.yaml versions it with the compositions that decide what needs activating, so the two can't drift across releases, and drops the separate apply step from the install. The empty default activation stays in the installation guide: provider.defaultActivations=[] is a Crossplane Helm value, set before the Configuration installs, so it can't travel in the package. Signed-off-by: Nic Cope <nicc@rk0n.org>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Towards #334.
Installing Modelplane hard-depends on seven cloud provider families whose CRDs total around 900 on the control plane, but the compositions only ever compose about 40 managed resource kinds. Crossplane's default activation policy turns them all on (
"*"), so a fresh install pays the API-server and controller memory for ~900 CRDs it never uses, the idle footprint reported in #323.Crossplane v2 converts each provider CRD into an inactive ManagedResourceDefinition and only creates the CRD once a ManagedResourceActivationPolicy names it. This ships such a policy in the Configuration package (
apis/mrap.yaml, whichcrossplane project buildcollects like an XRD or Composition), naming exactly the kinds the compositions compose, and installs Crossplane with an empty default activation (provider.defaultActivations=[]) so that policy is the only thing activating managed resources.Measured on a kind install of v0.1.0-dev.1784158975.g3e46dfb: 107 CRDs instead of 912, and 7.2 GiB total instead of 12.3 GiB, with kube-apiserver at 1.3 GiB instead of 4.4 GiB. All 15 providers stayed healthy.
The activation list is hand-maintained, so a managed resource kind added to a composition without a matching entry here silently fails to activate, because its CRD won't exist. I derived the current 43 entries from the functions' model imports and cross-checked each against live MRDs, but there's no CI guard against future drift yet.
I have:
nix flake check(or./nix.sh flake check) and made sure it passes.Added or updated tests covering any composition function changes.(no composition function changes)git commit -s.