github.com/koderover/helm@v2.17.0+incompatible/docs/chart_template_guide/yaml_techniques.md (about) 1 # YAML Techniques 2 3 Most of this guide has been focused on writing the template language. Here, 4 we'll look at the YAML format. YAML has some useful features that we, as 5 template authors, can use to make our templates less error prone and easier 6 to read. 7 8 ## Scalars and Collections 9 10 According to the [YAML spec](https://yaml.org/spec/1.2/spec.html), there are two 11 types of collections, and many scalar types. 12 13 The two types of collections are maps and sequences: 14 15 ```yaml 16 map: 17 one: 1 18 two: 2 19 three: 3 20 21 sequence: 22 - one 23 - two 24 - three 25 ``` 26 27 Scalar values are individual values (as opposed to collections) 28 29 ### Scalar Types in YAML 30 31 In Helm's dialect of YAML, the scalar data type of a value is determined by a 32 complex set of rules, including the Kubernetes schema for resource definitions. 33 But when inferring types, the following rules tend to hold true. 34 35 If an integer or float is an unquoted bare word, it is typically treated as 36 a numeric type: 37 38 ```yaml 39 count: 1 40 size: 2.34 41 ``` 42 43 But if they are quoted, they are treated as strings: 44 45 ```yaml 46 count: "1" # <-- string, not int 47 size: '2.34' # <-- string, not float 48 ``` 49 50 The same is true of booleans: 51 52 ```yaml 53 isGood: true # bool 54 answer: "true" # string 55 ``` 56 57 The word for an empty value is `null` (not `nil`). 58 59 Note that `port: "80"` is valid YAML, and will pass through both the 60 template engine and the YAML parser, but will fail if Kubernetes expects 61 `port` to be an integer. 62 63 In some cases, you can force a particular type inference using YAML node tags: 64 65 ```yaml 66 coffee: "yes, please" 67 age: !!str 21 68 port: !!int "80" 69 ``` 70 71 In the above, `!!str` tells the parser that `age` is a string, even if it looks 72 like an int. And `port` is treated as an int, even though it is quoted. 73 74 75 ## Strings in YAML 76 77 Much of the data that we place in YAML documents are strings. YAML has more than 78 one way to represent a string. This section explains the ways and demonstrates 79 how to use some of them. 80 81 There are three "inline" ways of declaring a string: 82 83 ```yaml 84 way1: bare words 85 way2: "double-quoted strings" 86 way3: 'single-quoted strings' 87 ``` 88 89 All inline styles must be on one line. 90 91 - Bare words are unquoted, and are not escaped. For this reason, you have to 92 be careful what characters you use. 93 - Double-quoted strings can have specific characters escaped with `\`. For 94 example `"\"Hello\", she said"`. You can escape line breaks with `\n`. 95 - Single-quoted strings are "literal" strings, and do not use the `\` to 96 escape characters. The only escape sequence is `''`, which is decoded as 97 a single `'`. 98 99 In addition to the one-line strings, you can declare multi-line strings: 100 101 ```yaml 102 coffee: | 103 Latte 104 Cappuccino 105 Espresso 106 ``` 107 108 The above will treat the value of `coffee` as a single string equivalent to 109 `Latte\nCappuccino\nEspresso\n`. 110 111 Note that the first line after the `|` must be correctly indented. So we could 112 break the example above by doing this: 113 114 ```yaml 115 coffee: | 116 Latte 117 Cappuccino 118 Espresso 119 120 ``` 121 122 Because `Latte` is incorrectly indented, we'd get an error like this: 123 124 ``` 125 Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key 126 ``` 127 128 In templates, it is sometimes safer to put a fake "first line" of content in a 129 multi-line document just for protection from the above error: 130 131 ```yaml 132 coffee: | 133 # Commented first line 134 Latte 135 Cappuccino 136 Espresso 137 138 ``` 139 140 Note that whatever that first line is, it will be preserved in the output of the 141 string. So if you are, for example, using this technique to inject a file's contents 142 into a ConfigMap, the comment should be of the type expected by whatever is 143 reading that entry. 144 145 ### Controlling Spaces in Multi-line Strings 146 147 In the example above, we used `|` to indicate a multi-line string. But notice 148 that the content of our string was followed with a trailing `\n`. If we want 149 the YAML processor to strip off the trailing newline, we can add a `-` after the 150 `|`: 151 152 ```yaml 153 coffee: |- 154 Latte 155 Cappuccino 156 Espresso 157 ``` 158 159 Now the `coffee` value will be: `Latte\nCappuccino\nEspresso` (with no trailing 160 `\n`). 161 162 Other times, we might want all trailing whitespace to be preserved. We can do 163 this with the `|+` notation: 164 165 ```yaml 166 coffee: |+ 167 Latte 168 Cappuccino 169 Espresso 170 171 172 another: value 173 ``` 174 175 Now the value of `coffee` will be `Latte\nCappuccino\nEspresso\n\n\n`. 176 177 Indentation inside of a text block is preserved, and results in the preservation 178 of line breaks, too: 179 180 ```yaml 181 coffee: |- 182 Latte 183 12 oz 184 16 oz 185 Cappuccino 186 Espresso 187 ``` 188 189 In the above case, `coffee` will be `Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso`. 190 191 ### Indenting and Templates 192 193 When writing templates, you may find yourself wanting to inject the contents of 194 a file into the template. As we saw in previous chapters, there are two ways 195 of doing this: 196 197 - Use `{{ .Files.Get "FILENAME" }}` to get the contents of a file in the chart. 198 - Use `{{ include "TEMPLATE" . }}` to render a template and then place its 199 contents into the chart. 200 201 When inserting files into YAML, it's good to understand the multi-line rules above. 202 Often times, the easiest way to insert a static file is to do something like 203 this: 204 205 ```yaml 206 myfile: | 207 {{ .Files.Get "myfile.txt" | indent 2 }} 208 ``` 209 210 Note how we do the indentation above: `indent 2` tells the template engine to 211 indent every line in "myfile.txt" with two spaces. Note that we do not indent 212 that template line. That's because if we did, the file content of the first line 213 would be indented twice. 214 215 ### Folded Multi-line Strings 216 217 Sometimes you want to represent a string in your YAML with multiple lines, but 218 want it to be treated as one long line when it is interpreted. This is called 219 "folding". To declare a folded block, use `>` instead of `|`: 220 221 ```yaml 222 coffee: > 223 Latte 224 Cappuccino 225 Espresso 226 227 228 ``` 229 230 The value of `coffee` above will be `Latte Cappuccino Espresso\n`. Note that all 231 but the last line feed will be converted to spaces. You can combine the whitespace 232 controls with the folded text marker, so `>-` will replace or trim all newlines. 233 234 Note that in the folded syntax, indenting text will cause lines to be preserved. 235 236 ```yaml 237 coffee: >- 238 Latte 239 12 oz 240 16 oz 241 Cappuccino 242 Espresso 243 ``` 244 245 The above will produce `Latte\n 12 oz\n 16 oz\nCappuccino Espresso`. Note that 246 both the spacing and the newlines are still there. 247 248 ## Embedding Multiple Documents in One File 249 250 It is possible to place more than one YAML documents into a single file. This 251 is done by prefixing a new document with `---` and ending the document with 252 `...` 253 254 ```yaml 255 256 --- 257 document:1 258 ... 259 --- 260 document: 2 261 ... 262 ``` 263 264 In many cases, either the `---` or the `...` may be omitted. 265 266 Some files in Helm cannot contain more than one doc. If, for example, more 267 than one document is provided inside of a `values.yaml` file, only the first 268 will be used. 269 270 Template files, however, may have more than one document. When this happens, 271 the file (and all of its documents) is treated as one object during 272 template rendering. But then the resulting YAML is split into multiple 273 documents before it is fed to Kubernetes. 274 275 We recommend only using multiple documents per file when it is absolutely 276 necessary. Having multiple documents in a file can be difficult to debug. 277 278 ## YAML is a Superset of JSON 279 280 Because YAML is a superset of JSON, any valid JSON document _should_ be valid 281 YAML. 282 283 ```json 284 { 285 "coffee": "yes, please", 286 "coffees": [ 287 "Latte", "Cappuccino", "Espresso" 288 ] 289 } 290 ``` 291 292 The above is another way of representing this: 293 294 ```yaml 295 coffee: yes, please 296 coffees: 297 - Latte 298 - Cappuccino 299 - Espresso 300 ``` 301 302 And the two can be mixed (with care): 303 304 ```yaml 305 coffee: "yes, please" 306 coffees: [ "Latte", "Cappuccino", "Espresso"] 307 ``` 308 309 All three of these should parse into the same internal representation. 310 311 While this means that files such as `values.yaml` may contain JSON data, Helm 312 does not treat the file extension `.json` as a valid suffix. 313 314 ## YAML Anchors 315 316 The YAML spec provides a way to store a reference to a value, and later 317 refer to that value by reference. YAML refers to this as "anchoring": 318 319 ```yaml 320 coffee: "yes, please" 321 favorite: &favoriteCoffee "Cappucino" 322 coffees: 323 - Latte 324 - *favoriteCoffee 325 - Espresso 326 ``` 327 328 In the above, `&favoriteCoffee` sets a reference to `Cappuccino`. Later, that 329 reference is used as `*favoriteCoffee`. So `coffees` becomes 330 `Latte, Cappuccino, Espresso`. 331 332 While there are a few cases where anchors are useful, there is one aspect of 333 them that can cause subtle bugs: The first time the YAML is consumed, the 334 reference is expanded and then discarded. 335 336 So if we were to decode and then re-encode the example above, the resulting 337 YAML would be: 338 339 ```yaml 340 coffee: yes, please 341 favorite: Cappucino 342 coffees: 343 - Latte 344 - Cappucino 345 - Espresso 346 ``` 347 348 Because Helm and Kubernetes often read, modify, and then rewrite YAML files, 349 the anchors will be lost.