<p>Is there a way to move boilerplate YAML from subchart templates to the parent <em>_helpers.tpl</em> or <em>values.yaml</em> ?</p>

<p><strong>helm project</strong></p>

<pre><code>    MyHelmApp
    │
    ├── Chart.yaml
    ├── values.yaml
    ├── templates
    │   ├── _helpers.tpl
    │   ├── configmap.yaml
    │   └── app-ingress-rules.yaml
    │
    └── charts
        │
        ├── app1
        │   ├── Chart.yaml
        │   ├── templates
        │   │   ├── _helpers.tpl
        │   │   ├── deployment.yaml
        │   │   └── service.yaml
        │   └── values.yaml
        ├── app2
        │   ├── Chart.yaml
        │   ├── templates
        │   │   ├── _helpers.tpl
        │   │   ├── deployment.yaml
        │   │   └── service.yaml
        │   └── values.yaml
        └── app3
            ├── Chart.yaml
            ├── templates
            │   ├── _helpers.tpl
            │   ├── deployment.yaml
            │   └── service.yaml
            └── values.yaml

</code></pre>

<p>To elaborate: I have 3 app subcharts and they each have boilerplate YAML in their templates. The values in those templates are defined in the parent chart's values.yaml, and the variable paths are identical. For instance:</p>

<p><strong>app1, app2, and app3 deployment.yaml's all contain...</strong></p>

<pre><code>          livenessProbe:
            httpGet:
              path: {{ .Values.health.livenessProbe.path }}
              port: {{ .Values.health.livenessProbe.port }}
            initialDelaySeconds: {{ .Values.health.livenessProbe.initialDelaySeconds }}
            periodSeconds: {{ .Values.health.livenessProbe.periodSeconds }}
            timeoutSeconds: {{ .Values.health.livenessProbe.timeoutSeconds }}
            successThreshold: {{ .Values.health.livenessProbe.successThreshold }}
            failureThreshold: {{ .Values.health.readinessProbe.failureThreshold }}

          readinessProbe:
            tcpSocket:
              port: {{ .Values.health.readinessProbe.port }}
            initialDelaySeconds: {{ .Values.health.readinessProbe.initialDelaySeconds }}
            periodSeconds: {{ .Values.health.readinessProbe.periodSeconds }}
            timeoutSeconds: {{ .Values.health.readinessProbe.timeoutSeconds }}
            successThreshold: {{ .Values.health.livenessProbe.successThreshold }}
            failureThreshold: {{ .Values.health.readinessProbe.failureThreshold }}
</code></pre>

<p><strong>values.yaml (in the parent chart)</strong></p>

<pre><code>app1:
  health:
    livenessProbe:
      path: /system_health
      port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 3
    readinessProbe:
      port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 3

app2:
  health:
    livenessProbe:
      path: /system_health
      port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 3
    readinessProbe:
      port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 3

(etc)
</code></pre>

<p>Back to the question: I'd like to grab what's identical in the subchart templates and move it to one centralized place like the parent chart's _helpers.tpl or values.yaml; is this possible?  Can you provide an example of how you'd do this? </p>

Mario Aguilera
<p>Helm renders all of the YAML it's given, from all parent and dependency charts together, in a single execution environment with a shared template namespace.  In theory, the <code>app1</code> chart can depend on a template that's defined in the parent's <code>_helpers.tpl</code>, and in the specific layout you show, it will work.</p>

<p>Because of this environment setup, it's also possible to write a "chart" that doesn't actually produce any YAML of its own, but just contains templates.  Helm 3 will include "library chart" as a specific concept.  A better layout still would be to have a library with your shared templates, and reference that.</p>

<pre><code>MyHelmApp
\-- charts
  +-- app1
  | +-- Chart.yaml
  | \-- templates/...
  \-- common
    +-- Chart.yaml
    \-- templates
      \-- _helpers.tpl
          (but no *.yaml)
</code></pre>

<p>Now <code>MyHelmApp</code> depends on <code>app1</code>, <code>app2</code>, and <code>app3</code>, and each of those depend on <code>common</code>.  This would let you install any of those independently from their siblings.</p>

<p>Helm doesn't have a way to "push" fragments of YAML into objects in other locations (<a href="https://kustomize.io" rel="nofollow noreferrer">Kustomize</a>, part of relatively recent Kubernetes, can does this).  Each object has to declare for itself any potential customization that could be allowed.  So in each chart you'd have to declare</p>

<pre><code>spec:
{{ include "common.probes" . | indent 2 }}
</code></pre>

<p>The common chart just defines templates, and when they're invoked they'd use the version of <code>.Values</code> that's localized to the subchart.</p>

<pre><code>{{- define "common.probes" -}}
livenessProbe:
  httpGet:
    path: {{ .Values.health.livenessProbe.path }}
    et: cetera
{{ end -}}
</code></pre>
