Skip to content
kix /docs
Install the CLI

How-to guide Adopt existing resources

Cede fields to a controller

Let an operator or Kubernetes controller retain ownership of selected fields without hiding unrelated apply conflicts.

Use ownership.cede when Kix must supply a field to create a resource but a controller is supposed to manage that field afterward. Common examples are an operator that rewrites a CRD’s served versions or admission webhook rules.

Ceding is deliberately narrow. Kix retries an apply only when every field in the API server’s conflict response is covered by a declared path. An unexpected conflict still stops the deploy.

Set ownership.cede on the resource that Kix renders:

crd = scope.mkCRD {
spec = upstream.spec;
ownership.cede = [ "spec.versions" ];
};

Use paths from the API server’s conflict message, without the leading dot. A path covers its descendants, so spec.versions also covers a conflict on an entry below that field.

For lists, [*] matches any indexed or keyed element. This is useful when a controller rewrites the rules in every webhook:

webhook = scope.mkClusterResource {
apiVersion = "admissionregistration.k8s.io/v1";
kind = "ValidatingWebhookConfiguration";
name = scope.instanceName;
ownership.cede = [ "webhooks[*].rules" ];
extra.webhooks = upstream.webhooks;
};

Declare the smallest path the controller needs. Ceding webhooks[*].rules does not permit a conflict on webhooks[*].clientConfig, for example.

Deploy normally:

❱ kix deploy my-cluster

On creation, Kix sends the complete field. After the controller takes ownership, a later deploy can receive a 409 Conflict. If all reported paths are ceded, Kix logs that another manager owns the ceded fields and retries once with those conflicting fields removed. The controller’s values remain in the live object.

Do not use --force-conflicts for this transition. That flag tells the API server to give the fields to Kix, so there is no conflict for the ceding logic to handle.

Inspect the resource after the controller has reconciled it:

❱ kubectl get validatingwebhookconfiguration my-operator -o yaml --show-managed-fields

Under metadata.managedFields, confirm that the controller owns the paths you ceded and that Kix still owns the fields it should manage. If the deploy still fails, read every path in the conflict. Add another path only when that field is intentionally controlled by the same controller.

ownership.cede does not ignore validation failures, immutable-field errors, or conflicts outside the declaration. For the opposite transition, where Kix must take a field from another manager, follow Handle server-side apply conflicts safely.