Kustomize’s inventory pruning feature can delete resources that were previously applied by Kustomize but are no longer present in the current Kustomize configuration, effectively cleaning up orphaned resources.

Let’s see this in action. Imagine you have a kustomization.yaml that applies a Deployment and a Service.

# kustomization.yaml
resources:
  - deployment.yaml
  - service.yaml

And the corresponding files:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: nginx
        image: nginx:latest
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

When you run kustomize build . and pipe it to kubectl apply -f -, Kustomize creates an inventory annotation on the applied resources. This annotation is a Kubernetes annotation starting with kustomize.config.k8s.io/. For example, you might see something like:

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "my-app",
    "annotations": {
      "kustomize.config.k8s.io/application": "kustomize-demo/my-app",
      "kustomize.config.k8s.io/instance": "kustomize-demo/my-app"
    }
  },
  // ... rest of deployment spec
}

The kustomize.config.k8s.io/application annotation is key. It acts as a unique identifier for the Kustomize application. When you run kustomize build again, it generates a new inventory. If resources with the same kustomize.config.k8s.io/application annotation are not present in the new build output, Kustomize knows they are orphaned and can be deleted.

Now, let’s say you decide to remove the service.yaml from your kustomization.yaml:

# kustomization.yaml
resources:
  - deployment.yaml

If you then run kustomize build . --inventory-policy=force and pipe that to kubectl apply -f -, Kustomize will compare the current state of your cluster (specifically, resources with the kustomize.config.k8s.io/application annotation matching your current Kustomize app) against the newly built resources. It will detect that the my-app-service is no longer in the build output, and since its kustomize.config.k8s.io/application annotation matches the current Kustomize application, it will generate a DELETE operation for that Service.

The inventory-policy flag controls this behavior.

  • none (default): Kustomize doesn’t manage inventory. No pruning occurs.
  • legacy: Kustomize attempts to manage inventory but might not be as robust.
  • force: Kustomize will explicitly manage inventory and enforce pruning. This is the policy you’ll want to use for active cleanup.

When you run kustomize build --inventory-policy=force, Kustomize generates a special resource called Inventory (of kind ConfigMap) in your cluster. This ConfigMap stores the inventory of resources applied by Kustomize. The kubectl apply -f - command then uses this Inventory ConfigMap to determine which resources are orphaned.

The core mechanism is Kustomize’s ability to track what it applied. It annotates resources with its own identifiers. When you re-run kustomize build, it generates a new set of resources. It then compares this new set with the set of resources it knows it applied previously (by looking at the Inventory ConfigMap or annotations on existing resources). Any resource that was previously applied by this specific Kustomize application (identified by the kustomize.config.k8s.io/application annotation) but is not present in the new build output is marked for deletion.

The most surprising true thing about Kustomize inventory pruning is that it relies on Kubernetes garbage collection principles, but Kustomize actively manages the "owner" reference for its applied resources, rather than relying solely on Kubernetes’ built-in owner references. Kustomize essentially acts as a higher-level orchestrator, maintaining its own record of what it deployed and what should be deleted when it’s no longer declared.

This mechanism is particularly powerful when dealing with complex applications where resources might be conditionally included or excluded based on environment variables or other logic within Kustomize. When a condition changes and a resource is no longer generated, Kustomize’s pruning will clean it up automatically upon the next apply.

The next concept you’ll likely encounter is managing Kustomize’s inventory across multiple kustomization.yaml files or directories, and understanding how to avoid accidental deletion when resources are managed by different Kustomize applications.

Want structured learning?

Take the full Kustomize course →