Skip to content
kix /docs
Install the CLI

How-to guide Adopt existing resources

Shadow a flavor-provided import with a managed package

Replace a flavor's weak infrastructure default with a Kix-managed provider for the same role.

Flavors can describe infrastructure that already exists in the target cluster as imports. These imports are weak providers: a managed package that claims the same infrastructure role takes precedence during dependency resolution.

This guide replaces the default StorageClass supplied by the kind flavor. The same pattern applies to another flavor import whose role binding is shadowable.

The replacement package must claim the same registered role as the import and satisfy that role’s output contract:

clusters/test-doc-how-tos.nix
storageProvider =
{ scope, ... }:
{
meta = {
description = "StorageClass for the documentation example";
owner = "platform";
roles = [ "storageClasses" ];
};
build =
{ self, ... }:
{
storageClass = scope.mkClusterResource {
apiVersion = "storage.k8s.io/v1";
kind = "StorageClass";
name = "local-path-retain";
extra = {
provisioner = "rancher.io/local-path";
reclaimPolicy = "Retain";
volumeBindingMode = "WaitForFirstConsumer";
};
};
root = {
resource = self.storageClass;
out.storageClassName = self.storageClass.out.name;
};
};
};

View source on GitHub ↗

The storageClasses role requires out.storageClassName. PVC packages use that value when they do not set a class explicitly.

Use a provisioner and parameters supported by the target cluster. The example adds a Retain class for kind’s local-path-provisioner.

For StorageClasses you do not need a package of your own: a storage-classes instance claims the same role and renders the classes you list in config.classes. See Configure storage classes and PVCs. Whichever provider you use, do not annotate its class storageclass.kubernetes.io/is-default-class where the flavor imports a default class: the cluster would then have two defaults, and storage-classes refuses it.

Add the provider as an ordinary cluster instance:

clusters/test-doc-how-tos.nix
instances.storage-system.storage = {
package = storageProvider;
};

View source on GitHub ↗

The kind flavor also declares a platform-storage import for the storageClasses role. Kix selects the managed storage instance and leaves the imported provider out of dependency resolution. Consumers do not need individual deps overrides.

Shadowing changes which provider Kix packages receive. It does not adopt, modify, or delete the infrastructure represented by the flavor import.

Evaluate the cluster and inspect the dependency graph:

❱ kix check doc-how-tos
❱ kix graph doc-how-tos --format tree

The generated PVC should depend on the managed StorageClass, not on the flavor’s import marker. Render the relevant resources when you want to confirm the selected name:

❱ kix build doc-how-tos --output json | jq '.[] | select(.kind == "StorageClass" or .kind == "PersistentVolumeClaim") | {kind, name: .metadata.name, storageClassName: .spec.storageClassName}'

See Configure storage classes and PVCs for the provider and consumer configuration together.