Skip to content
Install the CLI

How-to guide Adopt existing resources

Cede fields to a controller

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 retries once with those conflicting fields removed (and logs the retry at info level when you pass -v or set KIX_LOG=info). 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.