<p>If I have a values.yaml that looks something like this:</p>
<pre><code>imageName:
  portInfo:
    numberOfPorts: 11
    startingPort: 7980
  env:
    - name: &quot;MIN_PORT&quot;
      value: 7980
    - name: &quot;MAX_PORT&quot;
      value: 7990

</code></pre>
<p>Right now I have a function in _helpers.tpl that takes the .Values.portInfo.numberOfPorts and .Values.portInfo.startingPort and will loop through for each port value something like this into deployments.yaml:</p>
<pre><code>- containerPort: 7980
  protocol: TCP
- containerPort: 7981
...
</code></pre>
<p>This is what that function looks like:</p>
<pre><code>{{- define &quot;ports.list&quot; -}}
{{- $dbPorts := (.Values.issdbImage.portInfo.numberOfPorts | int) }}
{{- $startingPort := (.Values.issdbImage.portInfo.startingPort | int) }}

{{- range $i := until $dbPorts }}
    - containerPort: {{ add $startingPort $i }}
      protocol: TCP
{{- end }}
{{- end}}
</code></pre>
<p>What I want to do instead is use the function to instead grab the values under MIN_PORT and MAX_PORT and do the same thing.</p>
<p>Is this possible? And, if so, I'd appreciate suggestions on how this can be accomplished.</p>
<p>Thanks!</p>

Jackson
<p>That <code>env:</code> data structure will be hard to traverse from Helm template code.  The values you show can easily be computed, and instead of trying to inject a complete environment-variable block in Helm values, it might be easier to construct the environment variables in your template.</p>
<pre class="lang-yaml prettyprint-override"><code># templates/deployment.yaml -- NOT values.yaml
env:
{{- $p := .Values.imageName.portInfo }}
  - name: MIN_PORT
    value: {{ $p.startingPort }}
  - name: MAX_PORT
    value: {{ add $p.startingPort (sub $p.numberOfPorts 1) }}
</code></pre>
<hr />
<p>If you really absolutely can't change the values format, this is <em>possible</em>.  Write a helper function to get a value from the <code>.Values.env</code> list:</p>
<pre class="lang-yaml prettyprint-override"><code>{{/* Get a value from an association list, like a container env:
     array.  Each item of the alist is a dictionary with keys
     `name:` and `value:`.  Call this template with a list of two
     items, the alist itself and the key to look up; outputs the
     value as a string (an empty string if not found, all values
     concatenated together if there are duplicates). */}}
{{- define &quot;alist.get&quot; -}}
{{- $alist := index . 0 -}}
{{- $needle := index . 1 -}}
{{- range $k, $v := $alist -}}
{{- if eq $k $needle -}}
{{- $v -}}
{{- end -}}
{{- end -}}
{{- end -}}
</code></pre>
<p>Then in your generator template, you can call this with <code>.Values.env</code>, using the Helm-specific <a href="https://docs.helm.sh/docs/chart_template_guide/named_templates/#the-include-function" rel="nofollow noreferrer"><code>include</code> function</a> to invoke a template and get its result as a string, and then <a href="https://docs.helm.sh/docs/chart_template_guide/function_list/#type-conversion-functions" rel="nofollow noreferrer"><code>atoi</code></a> to convert that string to a number.</p>
<pre class="lang-yaml prettyprint-override"><code>{{- define &quot;ports.list&quot; -}}
{{- $startingPort := include &quot;alist.get&quot; (list .Values.env &quot;MIN_PORT&quot;) | atoi }}
{{- $endingPort := include &quot;alist.get&quot; (list .Values.env &quot;MAX_PORT&quot;) | atoi }}
{{- range untilStep $startingPort (add $endingPort 1) 1 -}}
- containerPort: {{ . }}
  protocol: TCP
{{ end -}}
{{- end -}}
</code></pre>
<p>This approach is both more complex and more fragile than directly specifying the configuration parameters in <code>values.yaml</code>.  Helm doesn't have great support for unit-testing complex templates (I've rigged up a test framework using <code>helm template</code> and <a href="https://github.com/kward/shunit2" rel="nofollow noreferrer">shunit2</a> in the past) and there's some risk of it going wrong.</p>
