Kustomize lets you apply labels and annotations to all resources defined in a kustomization.yaml, not just specific ones.

Let’s see it in action. Imagine you have a kustomization.yaml file like this:

resources:
  - deployment.yaml
  - service.yaml

And your deployment.yaml looks like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: main
        image: nginx:latest

And service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

If you run kustomize build . in this directory, you’ll get the raw YAML for both the deployment and the service, with no extra labels or annotations.

Now, let’s add some common labels and annotations to all resources managed by this kustomization. We’ll modify kustomization.yaml:

resources:
  - deployment.yaml
  - service.yaml

commonLabels:
  app.kubernetes.io/part-of: my-project
  environment: production

commonAnnotations:
  description: "This is my critical application deployment."
  "kustomize.config.k8s.io/managed-by": "kustomize"

Running kustomize build . again will now produce:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app.kubernetes.io/part-of: my-project
    environment: production
  annotations:
    description: "This is my critical application deployment."
    kustomize.config.k8s.io/managed-by: "kustomize"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: main
        image: nginx:latest
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
  labels:
    app.kubernetes.io/part-of: my-project
    environment: production
  annotations:
    description: "This is my critical application deployment."
    kustomize.config.k8s.io/managed-by: "kustomize"
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Notice how commonLabels and commonAnnotations were automatically merged into the metadata section of both the Deployment and the Service. Kustomize intelligently merges these with any existing labels or annotations, rather than overwriting them. If a key already exists, Kustomize will not overwrite it from commonLabels or commonAnnotations; it only adds keys that are not present. This is crucial for avoiding conflicts with resource-specific metadata.

This feature is incredibly powerful for ensuring consistency across your entire application stack. You can enforce organizational standards, compliance requirements, or operational tags (like environment: staging or team: backend) on every single Kubernetes resource Kustomize generates from a given kustomization.yaml. It scales your ability to manage metadata without duplicating it in every individual resource file.

The primary problem this solves is metadata sprawl and inconsistency. Without commonLabels and commonAnnotations, you’d have to manually add the same set of labels and annotations to every Deployment, Service, StatefulSet, ConfigMap, etc., that you define. This is error-prone and tedious, especially in larger projects. Kustomize’s commonLabels and commonAnnotations centralize this management, making your manifests cleaner and your metadata governance much more robust.

Internally, Kustomize reads your kustomization.yaml, identifies the resources it needs to process, and then for each resource, it checks for the presence of commonLabels and commonAnnotations. If found, it takes the key-value pairs from these fields and applies them to the metadata.labels and metadata.annotations of the resource’s manifest, respectively. It performs a deep merge, ensuring that existing metadata is preserved while new metadata is added.

A common point of confusion is how Kustomize handles conflicts. If a resource already has a label or annotation with the same key as one defined in commonLabels or commonAnnotations, the existing one on the resource takes precedence. Kustomize does not overwrite existing keys from commonLabels or commonAnnotations. This behavior is intentional to prevent accidental overrides of critical resource-specific metadata.

The next step in managing metadata across resources with Kustomize is to use patches to selectively modify or add metadata to specific resources, rather than applying it universally.

Want structured learning?

Take the full Kustomize course →