1"use strict";(self.webpackChunkhelm_www=self.webpackChunkhelm_www||[]).push([["24625"],{94367(e,n,a){a.r(n),a.d(n,{metadata:()=>t,default:()=>h,frontMatter:()=>s,contentTitle:()=>r,toc:()=>d,assets:()=>o});var t=JSON.parse('{"id":"chart_template_guide/variables","title":"Variables","description":"Using variables in templates.","source":"@site/versioned_docs/version-3/chart_template_guide/variables.md","sourceDirName":"chart_template_guide","slug":"/chart_template_guide/variables","permalink":"/docs/v3/chart_template_guide/variables","draft":false,"unlisted":false,"editUrl":"https://github.com/helm/helm-www/blob/main/versioned_docs/version-3/chart_template_guide/variables.md","tags":[],"version":"3","sidebarPosition":8,"frontMatter":{"title":"Variables","description":"Using variables in templates.","sidebar_position":8},"sidebar":"tutorialSidebar","previous":{"title":"Flow Control","permalink":"/docs/v3/chart_template_guide/control_structures"},"next":{"title":"Named Templates","permalink":"/docs/v3/chart_template_guide/named_templates"}}'),l=a(74848),i=a(28453);let s={title:"Variables",description:"Using variables in templates.",sidebar_position:8},r,o={},d=[];function c(e){let n={code:"code",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(n.p,{children:["With functions, pipelines, objects, and control structures under our belts, we\ncan turn to one of the more basic ideas in many programming languages:\nvariables. In templates, they are less frequently used. But we will see how to\nuse them to simplify code, and to make better use of ",(0,l.jsx)(n.code,{children:"with"})," and ",(0,l.jsx)(n.code,{children:"range"}),"."]}),"\n",(0,l.jsx)(n.p,{children:"In an earlier example, we saw that this code will fail:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:' {{- with .Values.favorite }}\n drink: {{ .drink | default "tea" | quote }}\n food: {{ .food | upper | quote }}\n release: {{ .Release.Name }}\n {{- end }}\n'})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"Release.Name"})," is not inside of the scope that's restricted in the ",(0,l.jsx)(n.code,{children:"with"})," block.\nOne way to work around scoping issues is to assign objects to variables that can\nbe accessed without respect to the present scope."]}),"\n",(0,l.jsxs)(n.p,{children:["In Helm templates, a variable is a named reference to another object. It follows\nthe form ",(0,l.jsx)(n.code,{children:"$name"}),". Variables are assigned with a special assignment operator:\n",(0,l.jsx)(n.code,{children:":="}),". We can rewrite the above to use a variable for ",(0,l.jsx)(n.code,{children:"Release.Name"}),"."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: {{ .Release.Name }}-configmap\ndata:\n myvalue: "Hello World"\n {{- $relname := .Release.Name -}}\n {{- with .Values.favorite }}\n drink: {{ .drink | default "tea" | quote }}\n food: {{ .food | upper | quote }}\n release: {{ $relname }}\n {{- end }}\n'})}),"\n",(0,l.jsxs)(n.p,{children:["Notice that before we start the ",(0,l.jsx)(n.code,{children:"with"})," block, we assign ",(0,l.jsx)(n.code,{children:"$relname := .Release.Name"}),". Now inside of the ",(0,l.jsx)(n.code,{children:"with"})," block, the ",(0,l.jsx)(n.code,{children:"$relname"})," variable still\npoints to the release name."]}),"\n",(0,l.jsx)(n.p,{children:"Running that will produce this:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'# Source: mychart/templates/configmap.yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: viable-badger-configmap\ndata:\n myvalue: "Hello World"\n drink: "coffee"\n food: "PIZZA"\n release: viable-badger\n'})}),"\n",(0,l.jsxs)(n.p,{children:["Variables are particularly useful in ",(0,l.jsx)(n.code,{children:"range"})," loops. They can be used on\nlist-like objects to capture both the index and the value:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:" toppings: |-\n {{- range $index, $topping := .Values.pizzaToppings }}\n {{ $index }}: {{ $topping }}\n {{- end }}\n\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Note that ",(0,l.jsx)(n.code,{children:"range"})," comes first, then the variables, then the assignment operator,\nthen the list. This will assign the integer index (starting from zero) to\n",(0,l.jsx)(n.code,{children:"$index"})," and the value to ",(0,l.jsx)(n.code,{children:"$topping"}),". Running it will produce:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:" toppings: |-\n 0: mushrooms\n 1: cheese\n 2: peppers\n 3: onions\n"})}),"\n",(0,l.jsxs)(n.p,{children:["For data structures that have both a key and a value, we can use ",(0,l.jsx)(n.code,{children:"range"})," to get\nboth. For example, we can loop through ",(0,l.jsx)(n.code,{children:".Values.favorite"})," like this:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: {{ .Release.Name }}-configmap\ndata:\n myvalue: "Hello World"\n {{- range $key, $val := .Values.favorite }}\n {{ $key }}: {{ $val | quote }}\n {{- end }}\n'})}),"\n",(0,l.jsxs)(n.p,{children:["Now on the first iteration, ",(0,l.jsx)(n.code,{children:"$key"})," will be ",(0,l.jsx)(n.code,{children:"drink"})," and ",(0,l.jsx)(n.code,{children:"$val"})," will be ",(0,l.jsx)(n.code,{children:"coffee"}),",\nand on the second, ",(0,l.jsx)(n.code,{children:"$key"})," will be ",(0,l.jsx)(n.code,{children:"food"})," and ",(0,l.jsx)(n.code,{children:"$val"})," will be ",(0,l.jsx)(n.code,{children:"pizza"}),". Running the\nabove will generate this:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'# Source: mychart/templates/configmap.yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: eager-rabbit-configmap\ndata:\n myvalue: "Hello World"\n drink: "coffee"\n food: "pizza"\n'})}),"\n",(0,l.jsxs)(n.p,{children:['Variables are normally not "global". They are scoped to the block in which they\nare declared. Earlier, we assigned ',(0,l.jsx)(n.code,{children:"$relname"})," in the top level of the template.\nThat variable will be in scope for the entire template. But in our last example,\n",(0,l.jsx)(n.code,{children:"$key"})," and ",(0,l.jsx)(n.code,{children:"$val"})," will only be in scope inside of the ",(0,l.jsx)(n.code,{children:"{{ range... }}{{ end }}"}),"\nblock."]}),"\n",(0,l.jsxs)(n.p,{children:["However, there is one variable that will always point to the root context: - ",(0,l.jsx)(n.code,{children:"$"})," -.\nThis can be very useful when you are looping\nin a range and you need to know the chart'
1s release name."]}),"\n",(0,l.jsx)(n.p,{children:"An example illustrating this:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'{{- range .Values.tlsSecrets }}\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: {{ .name }}\n labels:\n # Many helm templates would use `.` below, but that will not work,\n # however `$` will work here\n app.kubernetes.io/name: {{ template "fullname" $ }}\n # I cannot reference .Chart.Name, but I can do $.Chart.Name\n helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"\n app.kubernetes.io/instance: "{{ $.Release.Name }}"\n # Value from appVersion in Chart.yaml\n app.kubernetes.io/version: "{{ $.Chart.AppVersion }}"\n app.kubernetes.io/managed-by: "{{ $.Release.Service }}"\ntype: kubernetes.io/tls\ndata:\n tls.crt: {{ .certificate }}\n tls.key: {{ .key }}\n{{- end }}\n'})}),"\n",(0,l.jsx)(n.p,{children:"So far we have looked at just one template declared in just one file. But one of\nthe powerful features of the Helm template language is its ability to declare\nmultiple templates and use them together. We'll turn to that in the next\nsection."})]})}function h(e={}){let{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(c,{...e})}):c(e)}},28453(e,n,a){a.d(n,{R:()=>s,x:()=>r});var t=a(96540);let l={},i=t.createContext(l);function s(e){let n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.