YAML Techniques

    According to the YAML spec, there are twotypes of collections, and many scalar types.

    The two types of collections are maps and sequences:

    1. map:
    2. one: 1
    3. two: 2
    4. three: 3
    5. sequence:
    6. - one
    7. - two
    8. - three

    Scalar values are individual values (as opposed to collections)

    In Helm’s dialect of YAML, the scalar data type of a value is determined by acomplex set of rules, including the Kubernetes schema for resource definitions.But when inferring types, the following rules tend to hold true.

    If an integer or float is an unquoted bare word, it is typically treated asa numeric type:

    1. count: 1
    2. size: 2.34

    But if they are quoted, they are treated as strings:

    1. count: "1" # <-- string, not int
    2. size: '2.34' # <-- string, not float

    The same is true of booleans:

    1. isGood: true # bool
    2. answer: "true" # string

    The word for an empty value is null (not nil).

    Note that port: "80" is valid YAML, and will pass through both thetemplate engine and the YAML parser, but will fail if Kubernetes expectsport to be an integer.

    In some cases, you can force a particular type inference using YAML node tags:

    1. coffee: "yes, please"
    2. age: !!str 21
    3. port: !!int "80"

    In the above, !!str tells the parser that age is a string, even if it lookslike an int. And port is treated as an int, even though it is quoted.

    Strings in YAML

    Much of the data that we place in YAML documents are strings. YAML has more thanone way to represent a string. This section explains the ways and demonstrateshow to use some of them.

    There are three “inline” ways of declaring a string:

    1. way1: bare words
    2. way2: "double-quoted strings"
    3. way3: 'single-quoted strings'

    All inline styles must be on one line.

    • Double-quoted strings can have specific characters escaped with \. Forexample "\"Hello\", she said". You can escape line breaks with \n.
    • Single-quoted strings are “literal” strings, and do not use the \ toescape characters. The only escape sequence is '', which is decoded asa single '.In addition to the one-line strings, you can declare multi-line strings:

    The above will treat the value of coffee as a single string equivalent toLatte\nCappuccino\nEspresso\n.

    1. coffee: |
    2. Latte
    3. Cappuccino
    4. Espresso

    Because Latte is incorrectly indented, we’d get an error like this:

    In templates, it is sometimes safer to put a fake “first line” of content in amulti-line document just for protection from the above error:

    1. coffee: |
    2. # Commented first line
    3. Latte
    4. Cappuccino
    5. Espresso

    Note that whatever that first line is, it will be preserved in the output of thestring. So if you are, for example, using this technique to inject a file’s contentsinto a ConfigMap, the comment should be of the type expected by whatever isreading that entry.

    In the example above, we used | to indicate a multi-line string. But noticethat the content of our string was followed with a trailing \n. If we wantthe YAML processor to strip off the trailing newline, we can add a - after the|:

    1. coffee: |-
    2. Latte
    3. Cappuccino
    4. Espresso

    Now the coffee value will be: Latte\nCappuccino\nEspresso (with no trailing\n).

    Other times, we might want all trailing whitespace to be preserved. We can dothis with the |+ notation:

    1. coffee: |+
    2. Latte
    3. Cappuccino
    4. Espresso
    5. another: value

    Now the value of coffee will be Latte\nCappuccino\nEspresso\n\n\n.

    Indentation inside of a text block is preserved, and results in the preservationof line breaks, too:

    1. coffee: |-
    2. Latte
    3. 12 oz
    4. 16 oz
    5. Cappuccino
    6. Espresso

    In the above case, coffee will be Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso.

    When writing templates, you may find yourself wanting to inject the contents ofa file into the template. As we saw in previous chapters, there are two waysof doing this:

    • Use {{ .Files.Get "FILENAME" }} to get the contents of a file in the chart.

    Note how we do the indentation above: indent 2 tells the template engine toindent every line in “myfile.txt” with two spaces. Note that we do not indentthat template line. That’s because if we did, the file content of the first linewould be indented twice.

    Sometimes you want to represent a string in your YAML with multiple lines, butwant it to be treated as one long line when it is interpreted. This is called“folding”. To declare a folded block, use > instead of |:

    1. coffee: >
    2. Latte
    3. Cappuccino
    4. Espresso

    The value of coffee above will be Latte Cappuccino Espresso\n. Note that allbut the last line feed will be converted to spaces. You can combine the whitespacecontrols with the folded text marker, so >- will replace or trim all newlines.

    Note that in the folded syntax, indenting text will cause lines to be preserved.

    1. coffee: >-
    2. Latte
    3. 12 oz
    4. 16 oz
    5. Cappuccino
    6. Espresso

    The above will produce Latte\n 12 oz\n 16 oz\nCappuccino Espresso. Note thatboth the spacing and the newlines are still there.

    document:1

    document: 2…

    In many cases, either the —- or the may be omitted.

    Some files in Helm cannot contain more than one doc. If, for example, morethan one document is provided inside of a values.yaml file, only the firstwill be used.

    Template files, however, may have more than one document. When this happens,the file (and all of its documents) is treated as one object duringtemplate rendering. But then the resulting YAML is split into multipledocuments before it is fed to Kubernetes.

    We recommend only using multiple documents per file when it is absolutelynecessary. Having multiple documents in a file can be difficult to debug.

    YAML is a Superset of JSON

    Because YAML is a superset of JSON, any valid JSON document should be validYAML.

    1. {
    2. "coffee": "yes, please",
    3. "coffees": [
    4. "Latte", "Cappuccino", "Espresso"
    5. ]
    6. }

    The above is another way of representing this:

    1. coffee: yes, please
    2. coffees:
    3. - Latte
    4. - Cappuccino
    5. - Espresso

    And the two can be mixed (with care):

    1. coffee: "yes, please"
    2. coffees: [ "Latte", "Cappuccino", "Espresso"]

    All three of these should parse into the same internal representation.

    While this means that files such as values.yaml may contain JSON data, Helmdoes not treat the file extension .json as a valid suffix.

    The YAML spec provides a way to store a reference to a value, and laterrefer to that value by reference. YAML refers to this as “anchoring”:

    In the above, &favoriteCoffee sets a reference to Cappuccino. Later, thatreference is used as *favoriteCoffee. So coffees becomesLatte, Cappuccino, Espresso.

    While there are a few cases where anchors are useful, there is one aspect ofthem that can cause subtle bugs: The first time the YAML is consumed, thereference is expanded and then discarded.

    So if we were to decode and then re-encode the example above, the resultingYAML would be:

    1. coffee: yes, please
    2. favorite: Cappucino
    3. coffees:
    4. - Latte
    5. - Cappucino
    6. - Espresso