Answers: <p>You can't create a secret with a single key that contains data from multiple sources.</p>
  <p>Assuming that <code>app-default.properties</code>  contains:</p>
  <pre><code>name=TestApp
  version=1.0.0
  </code></pre>
  <p>And <code>app-dev.properties</code> contains:</p>
  <pre><code>debug=true
  </code></pre>
  <p>You can create a secret with multiple keys, one for each file:</p>
  <pre><code>secretGenerator:
    - name: my-secret
      files:
      - app-default.properties
      - app-dev.properties
  </code></pre>
  <p>That gets you:</p>
  <pre><code>apiVersion: v1
  data:
    app-default.properties: |
      version=1.0
      name=TestApp
    app-dev.properties: |
      debug=true
  kind: ConfigMap
  metadata:
    name: my-secret
  
  </code></pre>
  <p>You can create a secret with multiple keys corresponding to the non-conflicting values in multiple property-style files, like this:</p>
  <pre><code>secretGenerator:
    - name: my-secret
      envs:
      - app-default.properties
      - app-dev.properties
  </code></pre>
  <p>That gets you:</p>
  <pre><code>apiVersion: v1
  data:
    debug: &quot;true&quot;
    name: TestApp
    version: &quot;1.0&quot;
  kind: ConfigMap
  metadata:
    name: my-secret
  </code></pre>
  <p>(This won't work if both files define the same keys.)</p>
  <p>But if your goal is ultimately to have a file in your pod that contains the merged content of both files, you will need to add some logic in your manifests. For example, we could use an <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" rel="nofollow noreferrer"><code>initContainer</code></a> to perform the merge operation.</p>
  <p>Start with the &quot;multiple files&quot; version of the secret...</p>
  <pre><code>secretGenerator:
    - name: my-secret
      files:
      - app-default.properties
      - app-dev.properties
  </code></pre>
  <p>And then do something like this:</p>
  <pre><code>spec:
    volumes:
      - name: inputConfig
        secret:
          secretName: my-secret
      - name: outputConfig
        emptyDir: {}
    initContainers:
      - name: merge-config
        image: docker.io/alpine:latest
        volumeMounts:
        - name: inputConfig
          mountPath: /config-in
        - name: outputConfig
          mountPath: /config-out
        command:
        - /bin/sh
        - -c
        - |
          cat /config-in/app-default.properties /config-in/app-dev.properties |
            tac |
            awk -F= '!seen[$1]++' &gt; /config-out/app.properties
  </code></pre>
  <p>And in your application container, mount the <code>outputConfig</code> volume and use the <code>app.properties</code> file.</p>
  <p>In this example, if <code>app-default.properties</code> has:</p>
  <pre><code>name=TestApp
  version=1.0.0
  </code></pre>
  <p>And <code>app-dev.properties</code> contains:</p>
  <pre><code>debug=true
  version=dev
  </code></pre>
  <p>Then the generated <code>app.properties</code> file will have:</p>
  <pre><code>version=dev
  debug=true
  name=MyApp
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2024-05-19T20:41:21.187Z
Answers: 2024-05-19T21:20:17.247Z
Answers: 2024-05-19T21:20:17.247Z
Answers: larsks
Body: <p>I have <code>2</code> separate <code>properties</code> files which contain secrets. I would like to use <code>secretGenerator</code> and merge them into a single property (i.e. <code>app_properties</code>).</p>
  <p>Here's the code I'm using but it's not working:</p>
  <pre><code>apiVersion: kustomize.config.k8s.io/v1beta1
  kind: Kustomization
  secretGenerator:
  - name: my-secret
    files:
    - app_properties=app-default.properties
    - app_properties=app-dev.properties
  generatorOptions:
    disableNameSuffixHash: true
  </code></pre>
  <p>This obviously fails with an error:</p>
  <pre><code>error: configmap my-secret illegally repeats the key `app_properties`
  </code></pre>
  <p>I seem to be missing something, but not sure what. Looking at the docs it does sound like I could use <code>mergeBehavior</code> and have the <code>secretGenerator</code> create two secrets (one that creates and one that merges), but that did not work as well.</p>
  <p>Not sure if what I'm trying to do is possible and if I'm in the right direction. Any ideas?</p>
  
Tags: <kubernetes><kustomize>
Title: Using kustomize and secretGenerator how do you create a secret under one key but from multiple files?
UserDisplayName: tftd
ThreadText: # Using kustomize and secretGenerator how do you create a secret under one key but from multiple files?
  
  (Asked by: username_0 on 2024-05-17)
  
  I have `2` separate `properties` files which contain secrets. I would like to use `secretGenerator` and merge them into a single property (i.e. `app_properties`).
  
  Here's the code I'm using but it's not working:
  
  ```
  apiVersion: kustomize.config.k8s.io/v1beta1
  kind: Kustomization
  secretGenerator:
  - name: my-secret
    files:
    - app_properties=app-default.properties
    - app_properties=app-dev.properties
  generatorOptions:
    disableNameSuffixHash: true
  
  ```
  
  This obviously fails with an error:
  
  ```
  error: configmap my-secret illegally repeats the key `app_properties`
  
  ```
  
  I seem to be missing something, but not sure what. Looking at the docs it does sound like I could use `mergeBehavior` and have the `secretGenerator` create two secrets (one that creates and one that merges), but that did not work as well.
  
  Not sure if what I'm trying to do is possible and if I'm in the right direction. Any ideas?
  
  **Tags:** kubernetes, kustomize
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-05-19. Score: 0
  
  You can't create a secret with a single key that contains data from multiple sources.
  
  Assuming that `app-default.properties` contains:
  
  ```
  name=TestApp
  version=1.0.0
  
  ```
  
  And `app-dev.properties` contains:
  
  ```
  debug=true
  
  ```
  
  You can create a secret with multiple keys, one for each file:
  
  ```
  secretGenerator:
    - name: my-secret
      files:
      - app-default.properties
      - app-dev.properties
  
  ```
  
  That gets you:
  
  ```
  apiVersion: v1
  data:
    app-default.properties: |
      version=1.0
      name=TestApp
    app-dev.properties: |
      debug=true
  kind: ConfigMap
  metadata:
    name: my-secret
  
  ```
  
  You can create a secret with multiple keys corresponding to the non-conflicting values in multiple property-style files, like this:
  
  ```
  secretGenerator:
    - name: my-secret
      envs:
      - app-default.properties
      - app-dev.properties
  
  ```
  
  That gets you:
  
  ```
  apiVersion: v1
  data:
    debug: "true"
    name: TestApp
    version: "1.0"
  kind: ConfigMap
  metadata:
    name: my-secret
  
  ```
  
  (This won't work if both files define the same keys.)
  
  But if your goal is ultimately to have a file in your pod that contains the merged content of both files, you will need to add some logic in your manifests. For example, we could use an [`initContainer`](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) to perform the merge operation.
  
  Start with the "multiple files" version of the secret...
  
  ```
  secretGenerator:
    - name: my-secret
      files:
      - app-default.properties
      - app-dev.properties
  
  ```
  
  And then do something like this:
  
  ```
  spec:
    volumes:
      - name: inputConfig
        secret:
          secretName: my-secret
      - name: outputConfig
        emptyDir: {}
    initContainers:
      - name: merge-config
        image: docker.io/alpine:latest
        volumeMounts:
        - name: inputConfig
          mountPath: /config-in
        - name: outputConfig
          mountPath: /config-out
        command:
        - /bin/sh
        - -c
        - |
          cat /config-in/app-default.properties /config-in/app-dev.properties |
            tac |
            awk -F= '!seen[$1]++' > /config-out/app.properties
  
  ```
  
  And in your application container, mount the `outputConfig` volume and use the `app.properties` file.
  
  In this example, if `app-default.properties` has:
  
  ```
  name=TestApp
  version=1.0.0
  
  ```
  
  And `app-dev.properties` contains:
  
  ```
  debug=true
  version=dev
  
  ```
  
  Then the generated `app.properties` file will have:
  
  ```
  version=dev
  debug=true
  name=MyApp
  
  ```
  
  
  ---
  
  