Skip to content
kix /docs
Install the CLI

How-to guide Adopt existing resources

Preserve Helm-compatible labels

Render Helm-style app and release selectors while moving a workload under Kix management.

Use Helm-style labels when an existing workload selects Pods with the app and release keys. Keeping those selectors avoids an immutable-field change when Kix takes ownership.

Read the current workload selector and Pod template labels:

❱ kubectl get deployment helm-web -n apps -o jsonpath='{.spec.selector.matchLabels}{"\n"}{.spec.template.metadata.labels}{"\n"}'

Continue if the selector follows the common Helm shape, with both app and release set to the release name. For a different selector, use selectorLabels to copy it exactly.

Set labelStyle on the instance:

how-to/adoption/cluster.nix
apps.helm-web = {
package = webPackage;
labelStyle = "helm";
config = {
message = "Kix manages a Helm-labelled workload";
environment = "production";
};
};

View source on GitHub ↗

For this instance, Kix generates app = "helm-web" and release = "helm-web" as scope.selectorLabels. Packages built with Kix’s workload and Service helpers use the same pair consistently.

Evaluate the cluster:

kix-examples/
❱ kix check how-to-adoption
 TOOL       RESULT  DETAILS                       
 eval       pass    21 manifests evaluated        
 scorecard  pass    0 errors, 14 warnings, 2 info

Render the Deployment and Service to verify their labels and selectors:

kix-examples/ output excerpt
❱ kix build how-to-adoption --output json
[
  {
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
      "name": "helm-web",
      "namespace": "apps",
      "labels": {
        "app": "helm-web",
        "app.kubernetes.io/managed-by": "kix",
        "app.kubernetes.io/name": "helm-web",
        "release": "helm-web"
      }
    },
    "spec": {
      "selector": {
        "matchLabels": {
          "app": "helm-web",
          "release": "helm-web"
        }
      },
      "template": {
        "metadata": {
          "labels": {
            "app": "helm-web",
            "app.kubernetes.io/name": "helm-web",
            "release": "helm-web"
          }
        }
      }
    }
  },
  {
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
      "name": "helm-web",
      "namespace": "apps",
      "labels": {
        "app.kubernetes.io/managed-by": "kix",
        "release": "helm-web"
      }
    },
    "spec": {
      "selector": {
        "app": "helm-web",
        "release": "helm-web"
      }
    }
  }
]

Compare the rendered Deployment selector with the live selector from the first step. kix diff cannot make this comparison because it finds live resources through Kix’s management labels. A Helm-owned workload does not have those labels, so the diff shows it as a new resource.

Ask the API server to review the complete ownership change instead:

kix-examples/
❱ kix plan how-to-adoption

Because the selector is immutable, a mismatch appears in the plan as a write the deploy would stop on, before anything reaches the cluster.