# Select and configure a cluster flavor

A flavor supplies cluster defaults for a Kubernetes environment. Select one
near the beginning of the cluster's module list, then place project-specific
configuration after it.

## Select a flavor

The local application scenario targets kind:

<Snippet {...kindFlavor} />

Use the flavor matching the cluster you will deploy to. Kix includes provider
profiles for local, managed, and self-hosted Kubernetes environments. The
flavor can set values such as:

* Provider identity and Kubernetes assumptions.
* DNS and storage role bindings.
* Platform imports already supplied by the environment.
* Defaults for nodes, networking, and storage behavior.

A flavor is a module, so it belongs in the same `modules` list as the rest of
the cluster configuration.

## Put overrides after the flavor

Later modules can refine values supplied by the flavor:

```nix title="cluster.nix"
modules = [
  kix.flavors.kind

  {
    # The kind flavor binds the CNI role exclusively to kindnet. Release it
    # when the kind cluster was created with its default CNI disabled.
    cluster.roles.cni = {
      binding = "absent";
      provider = null;
    };

    networkPolicy.enable = false;
    namespaces.apps = { };
  }
];
```

Flavors set role bindings and capability flags with `lib.mkDefault`. A later
module can therefore override them with an ordinary assignment. Put the flavor
first so the cluster-specific choices that override it are easy to see.

## Keep environment selection explicit

When a repository targets several environments, define a cluster for each one
and select its flavor explicitly. Do not infer the flavor from the current
kubectl context. Evaluation should produce the same manifests without
contacting a cluster.

Put everything the environments share in a module they both import:

```nix title="clusters/dev.nix"
{ kix, packages }:

kix.buildCluster {
  name = "dev";
  # Modules receive `ref` and a minimal `kix` by default. Forward the full
  # `kix` and the package catalogue so shared modules can use them.
  specialArgs = { inherit kix packages; };
  modules = [
    kix.flavors.kind
    ./base.nix
  ];
}
```

```nix title="clusters/prod.nix"
{ kix, packages }:

kix.buildCluster {
  name = "prod";
  specialArgs = { inherit kix packages; };
  modules = [
    kix.flavors.eks
    ./base.nix
  ];
}
```

Register both in the flake:

```nix title="flake.nix"
clusters = {
  dev = ./clusters/dev.nix;
  prod = ./clusters/prod.nix;
};
```

`mkFlake` passes only `kix`, `packages`, and `pins` to a cluster function. If
the function requires another argument, such as an externally supplied
`flavor`, evaluation fails with `called without required argument`.

## Check the result

Run `check` after selecting or changing a flavor:

<Command {...check} />

Inspect the package list to see platform imports contributed by the flavor.
The two `import` rows come from the kind flavor, not from the cluster body:

<Command {...listPackages} />

:::note[Reference]
See [Provider profiles](/docs/v0.1/reference/flavors/provider-profiles/),
[platform imports](/docs/v0.1/reference/flavors/platform-imports/), and the
[flavor capability matrix](/docs/v0.1/reference/flavors/capability-matrix/) for the
settings supplied by each flavor.
:::