Common Transformers
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 appl
to every resource listed under resources
.
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.
- Github repo: joseeden/labs-kustomize
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
.
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
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
andnewTag
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
inkustomization.yaml
refers to the image namename
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