I have base/foo.yaml that I want to apply to all my environments and it partially looks like this
Kubernetes:
deploymentPatches:
- patch: |-
- {"op": "add", "path": "/spec/template/spec/volumes/-", "value": {"name": "volume", "secret": {"secretName": "my-secret"}}}
- {"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts/-", "value": {"mountPath": "/connections", "name": "volume"}}
Now I want to add environment-specific patches as well so my end goal after running e.g. kubectl kustomize accept
should either be
Kubernetes:
deploymentPatches:
- patch: |-
- {"op": "add", "path": "/spec/template/spec/volumes/-", "value": {"name": "volume", "secret": {"secretName": "my-secret"}}}
- {"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts/-", "value": {"mountPath": "/connections", "name": "volume"}}
- {"op": "add", "path": "/spec/template/spec/containers/0/env/-", "value": {"name": "MY_ENVIRONMENT", "value": "accept"}}
or
Kubernetes:
deploymentPatches:
- patch: |-
- {"op": "add", "path": "/spec/template/spec/volumes/-", "value": {"name": "volume", "secret": {"secretName": "my-secret"}}}
- {"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts/-", "value": {"mountPath": "/connections", "name": "volume"}}
- patch: |-
- {"op": "add", "path": "/spec/template/spec/containers/0/env/-", "value": {"name": "MY_ENVIRONMENT", "value": "accept"}}
How would I go about setting up my kustomize config to accomplish this? I've tried the following thus far:
kustomize.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base
patchesStrategicMerge:
- foo.yaml
accept/foo.yaml
Kubernetes:
deploymentPatches:
- patch: |-
- {"op": "add", "path": "/spec/template/spec/containers/0/env/-", "value": {"name": "MY_ENVIRONMENT", "value": "accept"}}
The issue I was experiencing is explained in the strategic merge patch docs;
In the standard JSON merge patch, JSON objects are always merged but lists are always replaced. Often that isn't what we want.
To solve this problem, Strategic Merge Patch uses the go struct tag of the API objects to determine what lists should be merged and which ones should not.
That is why it works to add additional containers (if you use different names for the containers you want to append) with patchesStrategicMerge
.
However, the objects and lists I was trying to append items to, were not setup that way and was therefor just replaced.
Since I'm not in a position to change the setup, the solution for me was to resort to patchesJson6902
.
patch.yaml
- op: add
path: /spec/Kubernetes/deploymentPatches/-
value:
patch: |-
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: MY_ENVIRONMENT
value: accept
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base
patchesJson6902:
- target:
group: mygroup
version: v1
kind: myobject
name: myname
path: patch.yaml