kustomize: Unable to handle 2+ resources kinds using `generateName:`

If you have the following kustomization.yaml

resources:
- pre-sync-job.yaml
- post-sync-job.yaml

Where both resources use generateName: instead of name:, e.g.:

apiVersion: batch/v1
kind: Job
metadata:
  generateName: before-
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      containers:
      - name: sleep
        image: alpine:latest
        command: ["sleep", "10"]
      restartPolicy: Never
  backoffLimit: 0

and

apiVersion: batch/v1
kind: Job
metadata:
  generateName: after-
  annotations:
    argocd.argoproj.io/hook: PostSync
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      containers:
      - name: sleep
        image: alpine:latest
        command: ["sleep", "10"]
      restartPolicy: Never
  backoffLimit: 0

Then when running kustomize build, you get the following error:

$ kustomize build .
Error: loadResMapFromBasesAndResources: rawResources failed to read Resources: id '"batch_v1_Job|noNamespace|noPrefix|noName"' already used

When only including one of resources independently, then kustomize build works for both manifests. But when both are used at the same time, kustomize seems to consider it as a collision. I think generateName needs to be included in the key being used to detect collisions.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 24 (9 by maintainers)

Most upvoted comments

I wouldn’t call this issue closed…

@Liujingfang1 kubectl apply does not work for resources which want to use generateName: instead of name:. This is because kubectl apply needs to:

  1. HTTP GET existing resource (by name
  2. look at last-applied-configuration
  3. calculate 3-way strategic merge patch
  4. HTTP PATCH existing resource

generateName: is used in place of name: when a user does not care about the name of the resource and wants one generated by the API server. But to create these resources, kubectl create needs to be used.

I want to understand more of your usage. It seems you only need to composing different resource files in a kustomization.yaml. Is that correct?

That’s correct, for this specific use case, I would just like to reference a bunch of resource files. I think not having transformations not working on resources without a name, seems like acceptable behavior.

Usually, kustomize is used via the pattern kustomize build | kubectl apply -f -. When having resources using the generateName feature, you’d restrict your kustomization to only work with kubectl create.

It makes sense to me that kustomize supports both named and generate-named resources, but what are the current use cases for that, given that kubectl apply doesn’t support the latter? So one would need to maintain two kustomizations for one app, one that’s applicable, and one that’s only createable. When thinking about this, I get the feeling that kubectl apply should also be capable of coping with generateName resources, by e.g. just skipping the diff/patch part and directly create those resources, since that’s the intent of using generateName in the first place. Was this already considered and maybe rejected?

Usually, kustomize is used via the pattern kustomize build | kubectl apply -f -.

I agree that this is the most common usage pattern, but I don’t think kustomize should be so limited in scope to only support this mode of operation. For example, why wouldn’t the following be an equally acceptable use of kustomize:

kustomize build | kubectl create -f -

In our case, kustomize is solving problem of configuration management, and we really just need it to render manifests. In our specific scenario (Argo CD), after running kustomize build, helm template, or ks show, we treat any resource annotated with argocd.argoproj.io/hook specially when we deploy an app. Namely, it doesn’t go through kubectl apply.

Without the ability to support generateName: I’m unable to convert some existing helm and ksonnet apps which can render the manifests using the equivalent helm template and ks show envname commands.

When thinking about this, I get the feeling that kubectl apply should also be capable of coping with generateName resources, by e.g. just skipping the diff/patch part and directly create those resources, since that’s the intent of using generateName in the first place. Was this already considered and maybe rejected?

While I agree with you, I searched kubernetes issues and found the following: https://github.com/kubernetes/kubernetes/pull/44527, which chose to document this instead of enabling kubectl apply to support creation.

Kustomize is designed to work with apply. It also relies on name to do a lot of transformations, such as name reference, adding nameprefix and so on. Even if we add the support for generateName, it doesn’t work with a series of kustomize transformations. Thus it doesn’t benefit a lot from kustomize. I want to understand more of your usage. It seems you only need to composing different resource files in a kustomization.yaml. Is that correct?