I'm trying to append some items to an array in a kustomization.
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- api.yaml
patches:
- path: patch.yaml
api.yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-api
namespace: ns
spec:
values:
pod:
env:
- name: Elastic__AuthenticationType
value: BasicAuth
patch.yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-api
namespace: ns
spec:
values:
pod:
env:
- name: MetaPod__AllowedClients
value: Test
expected:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-api
namespace: ns
spec:
values:
pod:
env:
- name: Elastic__AuthenticationType
value: BasicAuth
- name: MetaPod__AllowedClients
value: Test
actual:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-api
namespace: ns
spec:
values:
pod:
env:
- name: MetaPod__AllowedClients
value: Test
I could achieve this via json patching (rather than strategic merge), but for reasons, I have to use strategic merge.
I've read the documentation about $patch: merge
, and that doesn't seem to have any affect.
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-api
namespace: ns
spec:
values:
pod:
env:
- $patch: merge
name: MetaPod__AllowedClients
value: Test
> kustomize version
v5.4.2
The fundamental problem here is that Kustomize doesn't know how to merge a list in a HelmRelease object. For standard types (Pods, Deployments, Services, etc), Kustomize has built-in information about appropriate merge keys for lists. That is, given a Pod like this:
apiVersion: v1
kind: Pod
metadata:
name: "example"
spec:
containers:
- name: example
env:
- name: WIDGET_COLOR
value: red
And a kustomization.yaml
like this:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- pod.yaml
patches:
- patch: |
apiVersion: v1
kind: Pod
metadata:
name: "example"
spec:
containers:
- name: example
env:
- name: WIDGET_SIZE
value: large
Kustomize knows the the name
attribute is the appropriate merge key for spec.containers.env
. If the patch introduces a new value
for an existing name
, the value
will be updated. If the patch introduces a new name
, that will be added to the list.
For non-standard types, it is often possible to provide this information to Kustomize explicitly using the openapi
option, which is documented here with examples here. You can fetch the schema from your kubernetes server using kustomize openapi fetch > openapi.json
.
Unfortunately, this isn't going to help you, because there is no standard schema for HelmRelase.spec.values
: the structure of the values is entirely up to the template designer, which is why the HelmRelease schema includes:
"spec": {
"x-kubernetes-preserve-unknown-fields": true
},
That means, "we don't care about or validate any attributes of the HelmRelease.spec
".
You could create a custom schema that applies to your particular configuration, but you probably don't want to do that: it would apply to all HelmRelease objects, which means that as soon as you have more than one it wouldn't be useful.
Ultimately, I think your best bet is to use JSONPatch patches to update fields in HelmRelease.spec.values
.