I'm updating some of my Kubernetes configurations to use 'replacements' and 'resources' in kustomize as 'vars' and 'bases' have been deprecated.
Previously, I used 'vars' in a base (/base/secrets/) like this:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: test_secret
env: secret.env
vars:
- name : SECRET_VALUE
objref:
kind: Secret
name: test_secret
apiVersion: v1
fieldref:
fieldpath: metadata.name
This base was used in various overlays for different services:
namespace: test-overlay
bases:
- ../../base/secrets/
- ../../base/service/
Now, with 'resources' and 'replacements', my understanding is that it's not possible to replace values in /base/service/ from /base/secrets/ as before. I could apply the 'replacement' in the overlay itself and target the base I want to modify, but I would prefer to perform the operation from a base for reusability and ease of use.
Here's what I'm trying to do:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: test_secret
env: secret.env
replacements:
- source:
name: test_secret
kind: Secret
targets:
- select:
kind: Deployment
name: service
fieldPaths:
- spec.template.spec.<field>
In the 'replacements' directive, spec.template.spec.<field> is the field in the Deployment resource that I'm trying to replace.
I'm using kustomize version v5.1.0.
How can I get 'replacements' to target other bases so that they can be used from any overlay? What's the best practice for this scenario?
I've attempted to apply the 'replacements' in the overlay itself and target the base I want to modify like this:
namespace: test-overlay
resources:
- ../../base/secrets/
- ../../base/service/
replacements:
- source:
kind: Secret
name: test_secret
targets:
- select:
kind: Deployment
name: service
fieldPaths:
- spec.template.spec.<field>
While this does apply the replacement to the service, it's not a satisfactory solution for me because I have multiple overlays that all need to use the same replacement for various deployments. I would prefer to define the replacement once in a base, rather than having to define it in each overlay.
Edit: A more clear minimal reproducible example
/base
/secrets
kustomization.yaml
/service
deployment.yaml
kustomization.yaml
/overlays
/test-overlay
kustomization.yaml
With the /secrets/ implemented as:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: test_secret
env: secret.env
replacements:
- source:
name: test_secret
kind: Secret
targets:
- select:
kind: Deployment
name: service
fieldPaths:
- spec.template.spec.volumes.name
This would be the /service/:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: service
spec:
template:
spec:
volumes:
- name: placeholder_value
emptyDir: {}
With /test-overlay/
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: test-overlay
resources:
- ../../base/secrets/
- ../../base/service/
I've tried including the 'replacements' in the test-overlays kustomization file which did work but is less desirable then letting the replacement be defined in a base
Thanks for updating your question with an example.
The answer I've posted here is still the correct solution in terms of sharing a replacement configuration among multiple overlays, but there are some errors in your
replacementsyntax: you cannot targetspec.template.spec.volumes.name, becausevolumesis a list and has nonameattribute.You can only target list elements with a
[name=value]style selector, so:A
kustomization.yamlcan only apply transformations (labels, patches, replacements, etc) to resources that are emitted by thatkustomization.yaml-- which means that if you want a transformation to affect all resources, it needs to be applied in the "outermost" kustomization.This means that you can't place something in a "base" that will modify resources generated in your overlays.
But don't worry, there is a solution! Components allow you to reuse kustomization fragments. If we move your replacement configuration into a component, we can get the behavior you want.
For example, here is a project with a base and two overlays:
base/deployment.yamllooks like this:And
base/kustomization.yamllooks like:So the
basedirectory results in a Deployment, a Secret, and a ConfigMap. There are two overlays,env1andenv2. In both overlays I want to apply the same replacement configuration, so I put that intocomponents/replace-username-password/kustomization.yaml:Now in
overlays/env1/kustomization.yamlI can make use of this component:And the same in
overlays/env2: