Skip to main content

Common Transformers

Updated Apr 19, 2022 ·

Overview

Kustomize includes several common transformers out of the box.

  • commonLabels – Add the same labels to all resources
  • namePrefix/nameSuffix – Add a prefix/suffix to resource names
  • namespace – Place all resources in a given namespace
  • commonAnnotations – Add metadata annotations to all resources

These e simple fields you can set in your kustomization.yaml. They applto every resource listed under resources.

info

You will need a Kubernetes cluster to try out the examples.

To setup a basic cluster, you can use k3d.

Clone the Repository

To try out the examples in the sections below, clone the project repository from GitHub.

Clone and move into the project directory:

git clone https://github.com/joseeden/labs-kustomize.git 
cd code-samples/04-transformers/common-transformers

Project directory structure:

├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
├── base-img
│ ├── deployment.yaml
│ └── kustomization.yaml
├── base-v3
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
├── v1
│ ├── kustomization.yaml
│ └── transformers
│ └── label.yaml
├── v2
│ ├── kustomization.yaml
│ └── transformers
│ └── name-prefix.yaml
├── v3
│ └── kustomization.yaml
├── v4
│ ├── kustomization.yaml
│ └── transformers
│ └── annotations.yaml
├── v5
│ └── kustomization.yaml
├── v5-b
│ └── kustomization.yaml
└── v5-c
└── kustomization.yaml

Label Transformer

Use this when you want to add detailed labels with control over where they are applied.

  • v1/transformers/label.yaml

    apiVersion: builtin
    kind: LabelTransformer
    metadata:
    name: label-transformer
    labels:
    environment: dev
    version: v1
    fieldSpecs:
    - path: metadata/labels
    create: true
  • v1/kustomization.yaml

    resources:
    - ../base

    transformers:
    - transformers/label.yaml

Create the namespace and deploy the resources.

kubectl create ns test-lab-v1 
kubectl -n test-lab-v1 apply -k ./v1

Check that both Deployment and Service have labels: environment=dev and version=v1.

$ kubectl -n test-lab-v1 get deployment myapp --show-labels

NAME READY UP-TO-DATE AVAILABLE AGE LABELS
myapp 1/1 1 1 45s environment=dev,version=v1
$ kubectl -n test-lab-v1 get service myapp-service --show-labels

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
myapp-service ClusterIP 10.43.174.62 <none> 80/TCP 91s environment=dev,version=v1

Name Prefix/Suffix Transformer

Add a prefix to resource names to easily group or version them.

  • v2/transformers/name-prefix.yaml

    apiVersion: builtin
    kind: PrefixSuffixTransformer
    metadata:
    name: prefix-transformer
    prefix: v2-
    fieldSpecs:
    - path: metadata/name
  • v2/kustomization.yaml

    resources:
    - ../base

    transformers:
    - transformers/name-prefix.yaml

Create the namespace and deploy the resources.

kubectl create ns test-lab-v2 
kubectl -n test-lab-v2 apply -k ./v2

You should see resources named v2-myapp and v2-myapp-service.

$ kubectl -n test-lab-v2 get all

NAME READY STATUS RESTARTS AGE
pod/v2-myapp-86bcdfd4f-x5k77 1/1 Running 0 2m10s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/v2-myapp-service ClusterIP 10.43.72.62 <none> 80/TCP 2m10s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/v2-myapp 1/1 1 1 2m10s

NAME DESIRED CURRENT READY AGE
replicaset.apps/v2-myapp-86bcdfd4f 1 1 1 2m10s

Namespace Transformer

Namespace Transformers are used to set all resources under a specific namespace.

In this example, we’ll use the configs from base-v3 instead of base, since base was already deployed earlier using the overlays in v1 and v2.

info

Keep in mind: If a Deployment or Service already exists in the default namespace, applying it in another namespace (e.g. test-lab-dev) won't remove the original.

base-v3/
├── deployment.yaml
├── kustomization.yaml
└── service.yaml

Also, in this example, we are not using a separate configuration file to define the namespace transformer (or the new namespace). Instead, it is defined in-line in the kustomization.yaml file.

v3/kustomization.yaml

resources:
- ../base-v3

namespace: test-lab-dev
info

You can define the transformer either as in-line configuration, through a separate config file, or through using convenience fields.

For more information, please see Ways to Define Transformers

A few notes about the namespace:

  • The namespace field in kustomization.yaml does not create the namespace.
  • The NamespaceTransformer also does not create the namespace.

Having said, you must manually create the namespace before applying the overlay

kubectl create ns test-lab-dev 

Then deploy the changes:

kubectl apply  -k ./v3

All resources should be created inside the test-lab-dev namespace.

$ kubectl get all -n test-lab-dev
NAME READY STATUS RESTARTS AGE
pod/v3-myapp-677c5b7585-8jp6c 1/1 Running 0 17s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/v3-myapp-service ClusterIP 10.43.29.72 <none> 80/TCP 17s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/v3-myapp 1/1 1 1 17s

NAME DESIRED CURRENT READY AGE
replicaset.apps/v3-myapp-677c5b7585 1 1 1 17s

CommonAnnotations Transformer

Add common annotations to all resources for metadata tagging.

In this example, we'll use the config files in the v4 folder:

  • v4/transformers/annotations.yaml

    apiVersion: builtin
    kind: AnnotationsTransformer
    metadata:
    name: annotations-transformer
    annotations:
    team: devops
    managed-by: kustomize
    fieldSpecs:
    - path: metadata/annotations
    create: true
  • v4/kustomization.yaml

    resources:
    - ../base

    transformers:
    - transformers/annotations.yaml

Create the namespace for the resources:

kubectl create ns test-lab-v4 

Deploy the resources:

kubectl apply -k ./v4 -n test-lab-v4 

Then verify:

kubectl get deployment myapp -n test-lab-v4  -o yaml | grep -A 5 annotations
kubectl get service myapp-service -n test-lab-v4 -o yaml | grep -A 5 annotations

You should see annotations:

annotations:
managed-by: kustomize
team: devops

Image Transformer

We can use an image transformer to change container images or just their tags in Kubernetes manifests.

  • Can update image name or tag
  • Helps manage different environments

This lets you avoid editing YAML files directly and keeps things cleaner.

Replace Image Name

We can change the container image from one to another, like from NGINX to HAProxy.

  • Use name to match the original image
  • Use newName to set the new image

In this example, we'll use the base configs in the base-img folder:

base-img
├── deployment.yaml
├── kustomization.yaml

The base configs:

  • base-img/deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: web
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: web
    template:
    metadata:
    labels:
    app: web
    spec:
    containers:
    - name: web
    image: nginx
  • base-img/kustomization.yaml

    resources:
    - deployment.yaml

The transformers are defined in the v5 folder:

  • v5/kustomization.yaml

    resources:
    - ../base-img

    images:
    - name: nginx
    newName: haproxy

Create the namespace first:

kubectl create ns test-lab-v5

Next, apply the overlay config in v5:

kubectl apply -k ./v5 -n test-lab-v5

After applying the changes, the image in your deployment becomes haproxy.

$ kubectl describe deployment web -n test-lab-v5 | grep "Pod Template" -A 5

Pod Template:
Labels: app=web
Containers:
web:
Image: haproxy
Port: <none>

As an additional test, you can update the v5/kustomization.yaml to use nginx again:

resources:
- ../base-img

images:
- name: haproxy
newName: nginx

And then apply the changes:

kubectl apply -k ./v5 -n test-lab-v5

The image should now switch back to nginx:

```bash
$ kubectl describe deployment web -n test-lab-v5 | grep "Pod Template" -A 5

Pod Template:
Labels: app=web
Containers:
web:
Image: nginx
Port: <none>

Replace Image Tag Only

If you want to keep the image but change the tag, you can just use newTag.

  • Use name to match the image
  • Use newTag to change the version

This is useful when promoting a new version without changing the image base.

In this example, we'll still use the base config in base-img, but we'll use the transformer defined in `v5-b/kustomization.yaml':

resources:
- ../base-img

images:
- name: nginx
newTag: "2.4"

Apply the changes:

kubectl apply -n test-lab-v5 -k ./v5-b

Now your image becomes nginx:2.4.

$ kubectl describe deployment web -n test-lab-v5 | grep "Pod Template" -A 5 

Pod Template:
Labels: app=web
Containers:
web:
Image: nginx:2.4
Port: <none>

If you'd like to play around, you can update the `v5-b/kustomization.yaml' and use a different tag:

images:
- name: nginx
newTag: "2.4.10-staging"

Apply the changes once again:

kubectl apply -n test-lab-v5 -k ./v5-b

The image tag will now be set to nginx:2.4.10-staging.

Pod Template:
Labels: app=web
Containers:
web:
Image: nginx:2.4.10-staging
Port: <none>

Replace Both Image and Tag

Finally, you can change both image name and tag in one go.

  • Use both newName and newTag together
  • Applies changes across all matching containers

The v5-c/kustomization.yaml:

resources:
- ../base-img

images:
- name: nginx
newName: haproxy
newTag: "3.0-most-latest"

Apply the changes:

kubectl apply -n test-lab-v5 -k ./v5-c

The final result will be haproxy:3.0-most-latest.

$ kubectl describe deployment web -n test-lab-v5 | grep "Pod Template" -A 5 

Pod Template:
Labels: app=web
Containers:
web:
Image: haproxy:3.0-most-latest
Port: <none>

This makes it simple to manage deployments across multiple environments by keeping all image changes in one place.

Image Name vs Container Name

Be careful not to confuse image names with container names.

  • name in kustomization.yaml refers to the image name
  • name in the pod spec is the container name

Even if the container name is web, Kustomize looks only at the image (nginx in this case).

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx

Cleanup

To remove the resources across all the created namespaces:

kubectl delete all --all -n test-lab-dev
kubectl delete all --all -n test-lab-v1
kubectl delete all --all -n test-lab-v2
kubectl delete all --all -n test-lab-v3
kubectl delete all --all -n test-lab-v4
kubectl delete all --all -n test-lab-v5

You can then delete the namespaces by repeating the delete all command multiple times, or you can also define the namespaces in this way:

kubectl delete ns test-lab-{dev,v1,v2,v3,v4,v5}

Output:

namespace "test-lab-v1" deleted
namespace "test-lab-v2" deleted
namespace "test-lab-v3" deleted
namespace "test-lab-v4" deleted
namespace "test-lab-v5" deleted

Confirm that all the custom namespaces are deleted:

$ kubectl get ns

NAME STATUS AGE
default Active 19h
kube-node-lease Active 19h
kube-public Active 19h
kube-system Active 19h