<p>I want to add an initContainer to all of my pods (with a specific annotation) in my kustomize base. The newly added init container should be the first init container. My patch looks like this.</p>
<pre><code>patches:
  - target:
      kind: Pod
      annotationSelector: &quot;database_init=True&quot;
    patch: |-
      - op: add
        path: /spec/initContainers/0
        value:
          name: database-init
          ...
</code></pre>
<p>This works fine for all pods that already have an init container. Unfortunately, I have pods without init containers and there the patch fails with the error <code>add operation does not apply: doc is missing path: \&quot;/spec/initContainers/0\&quot;</code>.
How do I write a patch that works for all my pods?</p>
<p>Complete example:</p>
<pre><code>.
├── base
│   ├── kustomization.yaml
│   ├── pod-1.yaml
│   └── pod-2.yaml
└── overlay
    └── kustomization.yaml
</code></pre>
<pre><code># cat base/pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod-1
  annotations:
    database_init: True
spec:
  initContainers:
    - name: something
      image: alpine:latest
      command: [&quot;sleep&quot;, &quot;10&quot; ]
  containers:
    - name: main
      image: alpine:latest
      command: [ &quot;sleep&quot;, &quot;60&quot; ]
</code></pre>
<pre><code># cat base/pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod-2
  annotations:
    database_init: True
spec:
#   initContainers:
#     - name: something
#       image: alpine:latest
#       command: [&quot;sleep&quot;, &quot;10&quot; ]
  containers:
    - name: main
      image: alpine:latest
      command: [ &quot;sleep&quot;, &quot;60&quot; ]
</code></pre>
<pre><code># cat base/kustomization.yaml
resources:
  - pod-1.yaml
  - pod-2.yaml
</code></pre>
<pre><code># cat overlay/kustomization.yaml
resources:
  - ../base

patches:

  - target:
      kind: Pod
      annotationSelector: &quot;database_init=True&quot;
    patch: |-
      - op: add
        path: /spec/initContainers/0
        value:
          name: database-init
          image: alpine:latest
          command: [ &quot;sleep&quot;, 10 ]
</code></pre>
<p>Result:</p>
<pre><code>$ kubectl kustomize overlay
error: add operation does not apply: doc is missing path: &quot;/spec/initContainers/0&quot;: missing value
</code></pre>
<p>After uncommenting the init container of pod-2, everything works.</p>
<p>Edit: Added the annotationSelector.</p>
<p>Edit: Added the complete example code.</p>

briconaut
<p>JSONPatch patches in general are fundamentally unable to handle the &quot;append to existing list or create new list&quot; situation. See e.g. <a href="https://stackoverflow.com/q/47670366/147356">this question</a>.</p>
<p>Fortunately, with Kustomize 5.0.1 it appears to be possible to achieve your goal using a strategic merge patch. Given your example configuration, if I place the following in <code>overlay/kustomization.yaml</code>:</p>
<pre><code>apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base/

patches:
  - target:
      kind: Pod
      annotationSelector: database_init=True
    patch: |-
      apiVersion: v1
      kind: Pod
      metadata:
        name: __ignored__
      spec:
        initContainers:
          - name: database-init
            image: alpine:latest
            command:
              - init
              - the
              - database
</code></pre>
<p>Then running <code>kustomize build overlay</code> produces the following output:</p>
<pre><code>apiVersion: v1
kind: Pod
metadata:
  annotations:
    database_init: &quot;True&quot;
  name: mypod-1
spec:
  containers:
  - command:
    - sleep
    - &quot;60&quot;
    image: alpine:latest
    name: main
  initContainers:
  - command:
    - init
    - the
    - database
    image: alpine:latest
    name: database-init
  - command:
    - sleep
    - &quot;10&quot;
    image: alpine:latest
    name: something
---
apiVersion: v1
kind: Pod
metadata:
  annotations:
    database_init: &quot;True&quot;
  name: mypod-2
spec:
  containers:
  - command:
    - sleep
    - &quot;60&quot;
    image: alpine:latest
    name: main
  initContainers:
  - command:
    - init
    - the
    - database
    image: alpine:latest
    name: database-init
</code></pre>
