Skip to content

Patch package output with overlays

Use partsOverlays for a local change that the package does not expose through its typed config options. The overlay runs after the package builds and can replace returned parts for one instance.

This overlay rebuilds one ConfigMap with an adoption annotation while preserving its generated data:

how-to/adoption/cluster.nix (L49–L64)
partsOverlays = [
(
scope: _self: base:
let
patchedConfig = scope.mkResource {
inherit (base.clientConfig) apiVersion kind name;
inherit (base.clientConfig.rawManifest) data;
annotations."example.com/adopted-from" = "legacy-config";
};
in
{
clientConfig = patchedConfig;
root = patchedConfig;
}
)
];

View source on GitHub ↗

An overlay receives three arguments:

  • scope contains the resource builders for this instance.
  • self is the final recursive package result. Name it _self when the overlay does not need it.
  • base is the package result before this overlay runs.

The example reads the original resource fields from base.clientConfig, creates patchedConfig, then replaces both the named part and root. Updating root is necessary because the original package uses that ConfigMap as its root resource.

Keep the patch as narrow as possible and explicitly preserve every field you need. rawManifest contains only the rendered Kubernetes manifest. Rebuilding a part drops any labels or annotations that the overlay does not copy. It also drops requires and extraDeps, because those ordering edges are not part of the manifest.

Avoid overlaying a workload. Rebuilding a Deployment with the generic scope.mkResource skips the selector and Pod-template labels added by scope.mkDeployment. It also skips the network policies attached by the workload builders. Prefer overlaying a leaf resource, such as the ConfigMap in this example. For broader changes, add a typed option to the package.

Evaluate the cluster after adding the overlay:

Run in kix-examples/
❱ kix check how-to-adoption
 TOOL         RESULT  DETAILS                                                       
 eval         pass    20 manifests evaluated                                        
 kubeconform  pass    skipped (this validation tool is not yet integrated with Kix) 
 pluto        pass    skipped (this validation tool is not yet integrated with Kix) 
 kyverno      pass    skipped (this validation tool is not yet integrated with Kix) 
 scorecard    pass    0 errors, 14 warnings, 4 info

Render the patched resource:

Run in kix-examples/ Output excerpt
❱ kix build how-to-adoption --output json
{
  "apiVersion": "v1",
  "kind": "ConfigMap",
  "metadata": {
    "name": "legacy-api-client",
    "namespace": "apps",
    "annotations": {
      "example.com/adopted-from": "legacy-config"
    }
  },
  "data": {
    "endpoint": "http://legacy-api.legacy.svc.cluster.local:8080"
  }
}

The output retains the endpoint from the package and adds the example.com/adopted-from annotation.

If several instances need the same change, add a typed option to the package instead. If every package in the cluster needs a policy-driven transform, consider globalPartsOverlays rather than repeating an instance overlay.