Kustomize’s name prefix and suffix offer a surprisingly powerful way to manage resource naming across different environments without resorting to complex templating.

Imagine you’re deploying a microservice, let’s call it my-app, to a Kubernetes cluster. You want to ensure that all its associated Kubernetes resources — like Deployments, Services, ConfigMaps, etc. — are easily identifiable, especially when you have multiple instances of my-app running in different namespaces or for different environments (dev, staging, prod). Kustomize’s namePrefix and nameSuffix fields in your kustomization.yaml are designed precisely for this.

Let’s say you have a base set of Kubernetes manifests for my-app:

# base/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: my-app-container
        image: nginx:latest
        ports:
        - containerPort: 80

And a corresponding kustomization.yaml in your base directory:

# base/kustomization.yaml
resources:
- deployment.yaml

Now, you want to deploy this to a dev namespace and ensure all resources are prefixed with dev- and suffixed with -app. You create an overlays/dev directory:

# overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base

namePrefix: dev-
nameSuffix: -app

When you run kustomize build overlays/dev, Kustomize will take the resources from the base directory and apply the prefix and suffix to the metadata.name of each resource. The output will look something like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dev-my-app-app # <-- Notice the prefix and suffix applied
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app # <-- Labels are NOT modified by namePrefix/nameSuffix
    spec:
      containers:
      - name: my-app-container
        image: nginx:latest
        ports:
        - containerPort: 80

Notice that the app: my-app label in the spec.selector.matchLabels and spec.template.metadata.labels remains unchanged. namePrefix and nameSuffix only affect metadata.name. This is a crucial distinction. If you need to modify labels (e.g., to match the new names for selectors), you’d use commonLabels or patches.

The core problem Kustomize solves here is maintaining a clean, reusable base set of manifests while enabling environment-specific variations without duplication. Without Kustomize, you’d likely be copying your entire manifest directory for each environment and doing manual find-and-replace, which is error-prone and hard to maintain.

Let’s see how this plays out in a more complex scenario. Suppose you have a Service manifest in your base:

# base/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

And your overlays/dev/kustomization.yaml has namePrefix: dev- and nameSuffix: -app. The generated Service would be:

apiVersion: v1
kind: Service
metadata:
  name: dev-my-app-svc-app # <-- Prefix and suffix applied
spec:
  selector:
    app: my-app # <-- Selector unchanged
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Now, here’s the mental model: Kustomize walks through your resource list. For each resource, it reads its metadata.name. If namePrefix is set, it prepends that string. If nameSuffix is set, it appends that string. The result is the new metadata.name for the resource that Kustomize will output or apply. This happens after all other transformations (like commonLabels, patches, etc.) have been applied to the resource’s content, but before the final output.

The real power comes when you have multiple overlays. For a prod environment, you might have:

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base

namePrefix: prod-
nameSuffix: -production

Running kustomize build overlays/prod would yield:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prod-my-app-production # <-- Different prefix/suffix for prod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: nginx:latest
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: prod-my-app-svc-production # <-- Different prefix/suffix for prod
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

The most common pitfall when using namePrefix and nameSuffix is forgetting that they only modify metadata.name. If your Kubernetes resource relies on other resources by name (e.g., a Deployment referencing a ConfigMap by name, or a Service selector matching a Deployment’s labels), and those names are also being modified by namePrefix/nameSuffix, you’ll need to adjust those references. However, namePrefix/nameSuffix themselves do not automatically update selectors or other name-based references within the manifest. For instance, if you had a Service that explicitly referenced a ConfigMap by name, like:

# base/some-config-ref.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app-config
---
apiVersion: v1
kind: Pod
metadata:
  name: my-app-pod
spec:
  containers:
  - name: my-app-container
    image: alpine
    command: ["sleep", "3600"]
    env:
    - name: MY_CONFIG_VALUE
      valueFrom:
        configMapKeyRef:
          name: my-app-config # <-- Explicit name reference
          key: config.txt

And you apply namePrefix: dev- and nameSuffix: -app to this set of resources, your Pod’s configMapKeyRef.name will not automatically become dev-my-app-config-app. You would need to use a kustomize.config.k8s.io/v1beta1 patches or configMapGenerator with name field to achieve this.

The next logical step after mastering name prefixes and suffixes is understanding how to manage environment-specific configurations and secrets using ConfigMapGenerator and SecretGenerator.

Want structured learning?

Take the full Kustomize course →