<p>I am trying to setup the ability to have a dynamic number of volume and volumeMounts in my helm chart.  Here is how my deployment.yaml looks:</p>
<pre><code>    volumeMounts:
    {{- if .Values.deployment.hostPath }} {{ $dict := split &quot;:&quot; .Values.deployment.hostPath }} {{ range $idx, $val := $dict }} {{ $mnt := split &quot;,&quot; $val }}
    - mountPath: {{ $mnt._1 }}
      name: {{ $mnt._0 }}
    {{ end }}
    {{ end }}
  volumes:
  {{- if .Values.deployment.hostPath }} {{ $dict := split &quot;:&quot; .Values.deployment.hostPath }} {{ range $idx, $val := $dict }} {{ $mnt := split &quot;,&quot; $val }}
  - name: {{ $mnt._0 }}
    hostPath:
      path: {{ $mnt._2 }}
      {{- if $mnt._3 }}
      type: {{ $mnt._3 }}
      {{ end }}
  {{ end }}
  {{ end }}
</code></pre>
<p>In the values.yaml I have something like this:</p>
<pre><code>Deployment:
  hostPath: test-host-path,/path/on/pod,/path/on/node,Directory
</code></pre>
<p>What I am doing is checking if there is anything definied for hostPath. If there is I create a dict, spltting items by ':'.  In this first example, there is only one string of values, because the : delimeter isn't there.  It then does a range to loop (in case there are mutiple sets of values separated by ':') and then it splits a set of values by commas.</p>
<p>So with this first example, it works just fine using helm install:</p>
<pre><code>values.yaml --&gt;   hostPath: test-host-path,/path/on/pod,/path/on/node,Directory
        volumeMounts:
        - mountPath: /path/on/pod
          name: test-host-path

      volumes:
      - name: test-host-path
        hostPath:
          path: /path/on/node
          type: Directory
</code></pre>
<p>The type field is optional so I have a block to check if its defined, if not it doesnt render it in the yaml.  So on my next example when I just have no value after the last comma it also works:</p>
<pre><code>values.yaml --&gt;   hostPath: test-host-path,/path/on/pod,/path/on/node,
        volumeMounts:
        - mountPath: /path/on/pod
          name: test-host-path

      volumes:
      - name: test-host-path
        hostPath:
          path: /path/on/node
</code></pre>
<p>But now if I try to add a second set of data, separated by a ':', it fails on helm install:</p>
<pre><code>Deployment:
  hostPath: test-host-path,/path/on/pod,/path/on/node,Directory:test-host-path-two,/path/on/pod/two,/path/on/node/two,Directory

Error: YAML parse error on chart/templates/deployment.yaml: error converting YAML to JSON: yaml: line 152: found a tab character that violates indentation
helm.go:94: [debug] error converting YAML to JSON: yaml: line 152: found a tab character that violates indentation
</code></pre>
<p>Of course it's mentioning a tab, but I can't quite figure out what the issue is.  I have used this same code (dict,range,split) to populate multiple entries in a configmap so I think it can work. But clearly I am missing something here.  Any help would be appreciated.</p>

ssbsts
<p>It's not totally obvious where a tab character might be sneaking in.  One thing that does jump out is there's some extra whitespace hanging out in the templating; for example, there's a space after the start of the <code>{{ range }}</code> loop that potentially throws things off.</p>
<p>If you're having whitespace or indentation problems, one good thing to check is the <code>helm template</code> output; Helm 3 will print &quot;error converting YAML&quot; as you've shown if it's really wrong, but adding a <code>helm template --debug</code> option will print it anyways.</p>
<p>Other useful rules of thumb are to put only one templating construct on a line; to put a <code>-</code> &quot;swallow whitespace&quot; marker inside opening but not closing curly braces; and generally put templating constructs at the first column.  Those rules would get you something like</p>
<pre class="lang-yaml prettyprint-override"><code>    volumeMounts:
{{- if .Values.deployment.hostPath }}
{{- $dict := split &quot;:&quot; .Values.deployment.hostPath }}
{{- range $idx, $val := $dict }}
{{- $mnt := split &quot;,&quot; $val }}
    - mountPath: {{ $mnt._1 }}
      name: {{ $mnt._0 }}
{{- end }}
{{- end }}
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>  volumes:
{{- if .Values.deployment.hostPath }}
{{- $dict := split &quot;:&quot; .Values.deployment.hostPath }}
{{- range $idx, $val := $dict }}
{{- $mnt := split &quot;,&quot; $val }}
  - name: {{ $mnt._0 }}
    hostPath:
      path: {{ $mnt._2 }}
{{- if $mnt._3 }}
      type: {{ $mnt._3 }}
{{- end }}
{{- end }}
{{- end }}
</code></pre>
<p>You should be able to tell by inspection with this layout that the indentation is correct.  In the first example, there is a newline and spaces before <code>- mountPath:</code>, for example, and a newline following the last <code>{{- end }}</code>, but it should be clear there are not stray newlines or spaces between the templating code lines.</p>
