5

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"}}
Eirik H
  • 654
  • 2
  • 8
  • 30
  • What version of kustomize do you use? Did you get any error when you trying? – RadekW Mar 28 '22 at 13:25
  • I use the version that comes with kubectl 1.22.0, and the result is just that I get the deploymentPatch from foo.yaml (and not from the base). It replaces the list instead of appending to it like I want. – Eirik H Mar 28 '22 at 18:28
  • What is current stage/error/efect? Did you use any pattern? Could you provide a [minimal example](https://stackoverflow.com/help/minimal-reproducible-example) of deployment? – RadekW Mar 29 '22 at 14:42
  • On further research I believe the issue is explained here; https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md. "In the standard JSON merge patch, JSON objects are always merged but lists are always replaced." "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." Guess the object I'm trying to do this with is not marked as one that shouldn't be replaced. – Eirik H Mar 29 '22 at 19:49

1 Answers1

15

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
Eirik H
  • 654
  • 2
  • 8
  • 30