<p>I have multiple sucharts with applications and a parent chart that will deploy them.</p>
<p>All subcharts have the same manifests for the underlying application. Therefore I decided to create a library and put general variables from subcharts in it.</p>
<p>Example from lib:</p>
<pre><code>{{- define &quot;app.connect.common.release.common_libs.servicetemplate&quot; -}}  
apiVersion: v1
kind: Service
metadata:
  labels:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: &quot;true&quot;
  name: {{ .Values.application.name }}-service
  namespace: {{ .Values.global.environment.namespace }}
spec:
  type: LoadBalancer
  ports:
    - name: https
      port: 443
      targetPort: 8080
    - name: http
      port: 80
      targetPort: 8080
  selector:
    app: {{ .Values.application.name }}
status:
  loadBalancer: {}
{{- end }}
</code></pre>
<p>I declared a dependency in Chart.yaml and executed <code>helm dep up</code>. Then in my subchart I'm importing this template. But when I'm trying to run --dry-run on parent chart I'm receiving the following error:</p>
<pre><code>Error: template: app.connect.common.release/charts/app.connect.common.release.chtmgr/templates/service.yaml:1:4: executing &quot;app.connect.common.release/charts/app.connect.common.release.chtmgr/templates/service.yaml&quot; at &lt;include &quot;app.connect.common.release.common_libs.servicetemplate&quot; .&gt;: error calling include: template: app.connect.common.release/charts/app.connect.common.release.chtmgr/charts/app.connect.common.release.common_libs/templates/_helpers.tpl:169:18: executing &quot;app.connect.common.release.common_libs.servicetemplate&quot; at &lt;.Values.application.name&gt;: nil pointer evaluating interface {}.name
</code></pre>
<p>My values values.yaml in the subchart:</p>
<pre><code>application:
  name: chtmgr-api
  image: cht-mgr-api
</code></pre>
<p>The same error with named template.</p>
<p><strong>Is it possible to put general values from subchart in parent template(example _helper.tpl) and import it in subchart?</strong></p>
<p>If not, how do you implement this?</p>
<p>I've checked a lot of resources but still don't have an idea am I going in the right direction.</p>

DavidGreen55
<p>The Helm template <code>define</code> action creates a &quot;function&quot;.  It implicitly takes a single &quot;parameter&quot;, using the special variable name <code>.</code>, and <code>.Values</code> is actually a lookup in <code>.</code>.  It does not &quot;capture&quot; <code>.Values</code> at the point where it is defined; it uses the <code>Values</code> property of the parameter that's passed to it.</p>
<p>This means the template will behave differently when it's called in different contexts.  As the Helm documentation on <a href="https://docs.helm.sh/docs/chart_template_guide/subcharts_and_globals/" rel="nofollow noreferrer">Subcharts and Global Variables</a> describes, when executing the subchart, the top-level <code>.</code> parameter will have its <code>Values</code> replaced by the subchart's key in the primary values.</p>
<p>There's three ways to work around this:</p>
<ol>
<li><p>If you're using Helm 3, you can <a href="https://docs.helm.sh/docs/topics/charts/#using-the-child-parent-format" rel="nofollow noreferrer">directly import a value</a> from the subchart into the parent.  (I'm not clear what version of Helm exactly this was added, or if the syntax works in a separate <code>requirements.yaml</code> file.)  Declare the subchart dependency in your <code>Chart.yaml</code> as</p>
<pre class="lang-yaml prettyprint-override"><code>dependencies:
   - name: subchart
     import-values:
       - child: application
         parent: application
</code></pre>
<p>and the template you show should work unmodified.</p>
<p>(There's a <a href="https://docs.helm.sh/docs/topics/charts/#using-the-exports-format" rel="nofollow noreferrer">more involved path</a> that involves the subchart explicitly exporting values to the parent.  I'm not sure if this is that useful to you: the paths will still be different in the two charts, and in any case Helm values can't contain computed values.)</p>
</li>
<li><p>You already use <code>.Values.global</code> in your example; this will have the same value in the parent chart and all included charts.</p>
<pre class="lang-yaml prettyprint-override"><code>#                vvvvvv  inserted &quot;global&quot; here
name: {{ .Values.global.application.name }}-service
namespace: {{ .Values.global.environment.namespace }}
</code></pre>
</li>
<li><p>You can also use template logic to try to look in more places for the <code>application</code> dictionary.  This will only work from the parent chart and the subchart proper and not any other sibling charts; I believe it will also only work if the configuration is embedded in the parent chart's <code>values.yaml</code> or an external <code>helm install -f</code> values file, but won't find content in the included chart's <code>values.yaml</code>.</p>
<pre class="lang-yaml prettyprint-override"><code>{{/* Get the subchart configuration, or an empty dict (assuming we're in the parent) */}}
{{- $subchart := .Values.subchart | default dict -}}
{{/* Find the application values (assuming first we're in the subchart) */}}
{{- $application := .Values.application | default $subchart.application | default dict -}}
{{/* Then use it */}}
name: {{ $application.name }}-service
</code></pre>
<p>This logic sets the variable <code>$application</code>, normally, to <code>.Values.application</code>.  If that's not set (you're in the parent chart) then it in effect looks up <code>.Values.subchart.application</code>, and if that's not available either then it uses an empty dictionary.  This is (again, using programming terminology) eagerly evaluated – even if you're not falling back to the default, Helm will always look up <code>.Values.subchart</code> – so we use a second variable to have the <code>.Values.subchart</code>, or an empty dict (if you're in the subchart).  In both cases looking up a nonexistent key in an empty dict isn't an error but looking up on an unset value is.</p>
</li>
</ol>
