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.