`namePrefix`/`nameSuffix` in Components Do Not Rewrite `secretKeyRef` for External Generator Secrets
What happened?
When namePrefix/nameSuffix are declared inside a Component (not the root kustomization.yaml),
kustomize correctly transforms Secret.metadata.name but does not rewrite secretKeyRef.name
references in pod specs pointing to secrets produced by an external generator (e.g. ksops / exec generators).
The pod starts with a stale secretKeyRef.name that no longer matches the transformed Secret name:
Error: secret "app-secret" not foundEven though kustomize build produces a Secret named myapp-app-secret-prod, the CronJob references app-secret, the pre-transform base name.
secretKeyRef:
name: app-secret # NOT transformed - mismatches the Secret
key: API_KEYWhat did you expect to happen?
secretKeyRef.name should be rewritten to match Secret.metadata.name after name transforms are applied, the same behaviour kustomize provides for native secretGenerator:
secretKeyRef:
name: myapp-app-secret-prod # matches the transformed Secret name
key: API_KEYHow can we reproduce it (as minimally and precisely as possible)?
Structure
├── base/
│ ├── kustomization.yaml
│ └── cronjob.yaml
├── component/
│ └── kustomization.yaml
└── overlay-with-generator/
├── kustomization.yaml
├── secret-generator.yaml
└── app-secret.enc.yamlbase/cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: app-cronjob
spec:
schedule: "0 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: app
image: busybox
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: app-secret
key: API_KEYbase/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cronjob.yamlcomponent/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
namePrefix: myapp-
nameSuffix: -prodoverlay-with-generator/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: myapp-prod
components:
- ../component
resources:
- ../base
generators:
- secret-generator.yaml # exec/function generator (e.g. ksops) producing a Secret named app-secretoverlay-with-generator/secret-generator.yaml
apiVersion: viaduct.ai/v1
kind: ksops
metadata:
name: app-secret-generator
annotations:
config.kubernetes.io/function: |
exec:
path: ksops
files:
- app-secret.enc.yamloverlay-with-generator/app-secret.enc.yaml
A SOPS-encrypted file decrypting to:
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
API_KEY: my-api-keySteps
kustomize build overlay-with-generator --enable-alpha-plugins --enable-exec \
| grep -A3 "secretKeyRef"Root Cause
Kustomize tracks secretKeyRef > Secret cross-references only for secrets known at parse time
(base resources + native secretGenerator). Secrets produced by exec/function generators are injected
after the reference graph is built — their names are not tracked and secretKeyRef.name is never rewritten.
Additionally, namePrefix/nameSuffix inside a Component do not participate in reference tracking
even for base resources. Only transforms declared in the root kustomization.yaml trigger
automatic cross-reference rewrites.
Workarounds
Option 1 : Hardcode the transformed name in a patch
Patch secretKeyRef.name directly in the overlay's cronjob patch with the known final name:
containers:
- name: app
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: myapp-app-secret-prod
key: API_KEYDrawback: If
namePrefix/nameSuffixever change, this silently breaks — every patch referencing the secret must be updated manually.
Option 2 : replacements block
Add a replacements block in the overlay to propagate the transformed name dynamically:
replacements:
- source:
version: v1
kind: Secret
name: app-secret
fieldPath: metadata.name
targets:
- select:
kind: CronJob
name: app-cronjob
fieldPaths:
- spec.jobTemplate.spec.template.spec.containers.[name=app].env.[name=API_KEY].valueFrom.secretKeyRef.nameDrawback: Only works when namePrefix/nameSuffix are in the root kustomization.yaml.
When they are inside a Component, the replacement fails with:
nothing selected by Secret.v1.[noGrp]/app-secret.[noNs]:metadata.name because the source selector runs against the already-transformed name.
Expected output
secretKeyRef:
name: myapp-app-secret-prod # correctly rewritten
key: API_KEYActual output
secretKeyRef:
name: app-secret # NOT rewritten
key: API_KEYKustomize version
v5.8.1
Operating system
MacOS
Source: kubernetes-sigs/kustomize