`namePrefix`/`nameSuffix` in Components Do Not Rewrite `secretKeyRef` for External Generator Secrets
kind/bugneeds-triage
### 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 found
```
Even though `kustomize build` produces a Secret named `myapp-app-secret-prod`, the CronJob references `app-secret`, the pre-transform base name.
```yaml
secretKeyRef:
name: app-secret # NOT transformed - mismatches the Secret
key: API_KEY
```
### What 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`:
```yaml
secretKeyRef:
name: myapp-app-secret-prod # matches the transformed Secret name
key: API_KEY
```
### How 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.yaml
```
### `base/cronjob.yaml`
```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_KEY
```
### `base/kustomization.yaml`
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cronjob.yaml
```
### `component/kustomization.yaml`
```yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
namePrefix: myapp-
nameSuffix: -prod
```
### `overlay-with-generator/kustomization.yaml`
```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-secret
```
### `overlay-with-generator/secret-generator.yaml`
```yaml
apiVersion: viaduct.ai/v1
kind: ksops
metadata:
name: app-secret-generator
annotations:
config.kubernetes.io/function: |
exec:
path: ksops
files:
- app-secret.enc.yaml
```
### `overlay-with-generator/app-secret.enc.yaml`
A SOPS-encrypted file decrypting to:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
API_KEY: my-api-key
```
### Steps
```bash
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:
```yaml
containers:
- name: app
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: myapp-app-secret-prod
key: API_KEY
```
> **Drawback**: If `namePrefix`/`nameSuffix` ever 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:
```yaml
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.name
```
**Drawback**: 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
```yaml
secretKeyRef:
name: myapp-app-secret-prod # correctly rewritten
key: API_KEY
```
### Actual output
```yaml
secretKeyRef:
name: app-secret # NOT rewritten
key: API_KEY
```
### Kustomize version
v5.8.1
### Operating system
MacOS
1 条评论