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.
Create a managed provider
Section titled “Create a managed provider”The replacement package must claim the same registered role as the import and satisfy that role’s output contract:
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; }; }; };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 managed instance
Section titled “Add the managed instance”Add the provider as an ordinary cluster instance:
instances.storage-system.storage = { package = storageProvider; };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.
Check the replacement
Section titled “Check the replacement”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.