<p>I am trying to insert multiline json string into helm template for base64 encoding required for Kubernetes secret.</p>

<p>Goals:</p>

<ul>
<li>helm value is injected into json string</li>
<li>multi-line json string must be base64 encoded using <code>b64enc</code></li>
</ul>

<p><code>myfile1.json</code> does not work but <code>myfile2.json</code> works.
I prefer not to put entire json file in <code>values.yaml</code>.</p>

<pre><code>apiVersion: v1
kind: Secret
metadata:
  name: {{ template "mychart.fullname" . }}
  labels:
    app: {{ template "mychart.name" . }}
    chart: {{ template "mychart.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
type: Opaque
data:
  myfile.json: {{ |-
    {
      "item1": {
          "name": "{{ .Values.item1.name }}"
      },
      "item2": {
      }
    } | b64enc }}
  myfile2.json: {{ .Values.myfile2 | b64enc }}
</code></pre>

Steve
<p>You actually don't need to base64-encode the secret in the helm chart. If you use the <code>stringData</code> field instead of <code>data</code> field, Kubernetes knows that it needs to base64 encode the data upon the secret's deployment.</p>

<p>From the docs (<a href="https://kubernetes.io/docs/concepts/configuration/secret/#creating-a-secret-manually" rel="noreferrer">Source</a>):</p>

<blockquote>
  <p>The Secret contains two maps: <code>data</code> and <code>stringData</code>. The <code>data</code> field is used to store arbitrary data, encoded using base64. The <code>stringData</code> field is provided for convenience, and allows you to provide secret data as unencoded strings.</p>
</blockquote>

<p>So we can rewrite your secret using <code>stringData</code> instead of <code>data</code> and keep multiline json strings in templates like so:</p>

<pre><code>apiVersion: "v1"
kind: "Secret"
metadata:
  name: {{ template "mychart.fullname" . }}
  labels:
    app: {{ template "mychart.name" . }}
    chart: {{ template "mychart.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
type: "Opaque"
stringData:
  myfile.json: |-
    {
      "item1": {
          "name": "{{ .Values.item1.name }}"
      },
      "item2": {
      }
    }
  myfile2.json: {{ .Values.myfile2 }}
</code></pre>

<p>Note that this does not mean you suddenly need to worry about having unencoded secrets. <code>stringData</code> will ultimately be base64-encoded and converted to <code>data</code> when it is installed, so it will behave exactly the same once it's loaded into Kubernetes.</p>

<p>Again, from the docs <strong>(emphasis mine)</strong> (<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#secret-v1-core" rel="noreferrer">Source</a>):</p>

<blockquote>
  <p><code>stringData</code> allows specifying non-binary secret data in string form. <strong>It is provided as a write-only convenience method.</strong> All keys and values are merged into the <code>data</code> field on write, overwriting any existing values. <strong>It is never output when reading from the API.</strong></p>
</blockquote>
