Skip to content

Shadow a flavor-provided import with a managed package

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 (L7–L34)
storageProvider =
{ scope, ... }:
{
meta = {
version = "1.0.0";
description = "Default StorageClass for the documentation example";
roles = [ "storageClasses" ];
};
build =
{ self, ... }:
{
storageClass = scope.mkClusterResource {
apiVersion = "storage.k8s.io/v1";
kind = "StorageClass";
name = "example-local";
extra = {
provisioner = "kubernetes.io/no-provisioner";
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 uses a static local provisioner to keep the package small; it is not a general purpose dynamic storage configuration.

Add the provider as an ordinary cluster instance:

clusters/test-doc-how-tos.nix (L87–L89)
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.