github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/website/content/docs/job-specification/hcl2/expressions.mdx (about) 1 --- 2 layout: docs 3 page_title: Expressions - Configuration Language 4 sidebar_title: Expressions 5 description: |- 6 HCL allows the use of expressions to access data exported 7 by sources and to transform and combine that data to produce other values. 8 --- 9 10 # Expressions 11 12 _Expressions_ are used to refer to or compute values within a configuration. 13 The simplest expressions are just literal values, like `"hello"` or `5`, but 14 HCL also allows more complex expressions such as arithmetic, conditional 15 evaluation, and a number of built-in functions. 16 17 Expressions can be used in a number of places in HCL, particularly as attribute 18 values. Attribute value expressions must adhere to the attribute type. Block 19 labels must be string literals without any interpolation. Each language 20 feature's documentation describes any restrictions it places on expressions. 21 22 The rest of this page describes all of the features of Nomad's 23 expression syntax. 24 25 ## Types and Values 26 27 The result of an expression is a _value_. All values have a _type_, which 28 dictates where that value can be used and what transformations can be 29 applied to it. 30 31 HCL uses the following types for its values: 32 33 - `string`: a sequence of Unicode characters representing some text, like 34 `"hello"`. 35 - `number`: a numeric value. The `number` type can represent both whole 36 numbers like `15` and fractional values like `6.283185`. 37 - `bool`: either `true` or `false`. `bool` values can be used in conditional 38 logic. 39 - `list` (or `tuple`): a sequence of values, like 40 `["us-west-1a", "us-west-1c"]`. Elements in a list or tuple are identified by 41 consecutive whole numbers, starting with zero. 42 - `map` (or `object`): a group of values identified by named labels, like 43 `{name = "Mabel", age = 52}`. 44 45 Strings, numbers, and bools are sometimes called _primitive types._ 46 Lists/tuples and maps/objects are sometimes called _complex types,_ _structural 47 types,_ or _collection types._ 48 49 Finally, there is one special value that has _no_ type: 50 51 - `null`: a value that represents _absence_ or _omission._ If you set an 52 argument to `null`, Nomad behaves as though you 53 had completely omitted it — it will use the argument's default value if it has 54 one, or raise an error if the argument is mandatory. `null` is most useful in 55 conditional expressions, so you can dynamically omit an argument if a 56 condition isn't met. 57 58 ### Advanced Type Details 59 60 In most situations, lists and tuples behave identically, as do maps and objects. 61 Whenever the distinction isn't relevant, the Nomad documentation uses each 62 pair of terms interchangeably (with a historical preference for "list" and 63 "map"). 64 65 ### Type Conversion 66 67 Expressions are most often used to set values for arguments. In these cases, 68 the argument has an expected type and the given expression must produce a value 69 of that type. 70 71 Where possible, Nomad automatically converts values from one type to 72 another in order to produce the expected type. If this isn't possible, Nomad 73 will produce a type mismatch error and you must update the configuration with a 74 more suitable expression. 75 76 Nomad automatically converts number and bool values to strings when needed. 77 It also converts strings to numbers or bools, as long as the string contains a 78 valid representation of a number or bool value. 79 80 - `true` converts to `"true"`, and vice-versa 81 - `false` converts to `"false"`, and vice-versa 82 - `15` converts to `"15"`, and vice-versa 83 84 ## Literal Expressions 85 86 A _literal expression_ is an expression that directly represents a particular 87 constant value. Nomad has a literal expression syntax for each of the value 88 types described above: 89 90 - Strings are usually represented by a double-quoted sequence of Unicode 91 characters, `"like this"`. There is also a "heredoc" syntax for more complex 92 strings. String literals are the most complex kind of literal expression in 93 Nomad, and have additional documentation on this page: 94 - See [String Literals](#string-literals) below for information about escape 95 sequences and the heredoc syntax. 96 - See [String Templates](#string-templates) below for information about 97 interpolation and template directives. 98 - Numbers are represented by unquoted sequences of digits with or without a 99 decimal point, like `15` or `6.283185`. 100 - Bools are represented by the unquoted symbols `true` and `false`. 101 - The null value is represented by the unquoted symbol `null`. 102 - Lists/tuples are represented by a pair of square brackets containing a 103 comma-separated sequence of values, like `["a", 15, true]`. 104 105 List literals can be split into multiple lines for readability, but always 106 require a comma between values. A comma after the final value is allowed, 107 but not required. Values in a list can be arbitrary expressions. 108 109 - Maps/objects are represented by a pair of curly braces containing a series of 110 `<KEY> = <VALUE>` pairs: 111 112 ```hcl 113 { 114 name = "John" 115 age = 52 116 } 117 ``` 118 119 Key/value pairs can be separated by either a comma or a line break. Values 120 can be arbitrary expressions. Keys are strings; they can be left unquoted if 121 they are a valid [identifier](/docs/job-specification/hcl2/syntax#identifiers), but must be quoted 122 otherwise. You can use a non-literal expression as a key by wrapping it in 123 parentheses, like `(var.business_unit_tag_name) = "SRE"`. 124 125 ### Available Functions 126 127 For a full list of available functions, see [the function 128 reference](/docs/job-specification/hcl2/functions). 129 130 ## `for` Expressions 131 132 A _`for` expression_ creates a complex type value by transforming 133 another complex type value. Each element in the input value 134 can correspond to either one or zero values in the result, and an arbitrary 135 expression can be used to transform each input element into an output element. 136 137 For example, if `var.list` is a list of strings, then the following expression 138 produces a list of strings with all-uppercase letters: 139 140 ```hcl 141 [for s in var.list : upper(s)] 142 ``` 143 144 This `for` expression iterates over each element of `var.list`, and then 145 evaluates the expression `upper(s)` with `s` set to each respective element. 146 It then builds a new tuple value with all of the results of executing that 147 expression in the same order. 148 149 The type of brackets around the `for` expression decide what type of result 150 it produces. The above example uses `[` and `]`, which produces a tuple. If 151 `{` and `}` are used instead, the result is an object, and two result 152 expressions must be provided separated by the `=>` symbol: 153 154 ```hcl 155 {for s in var.list : s => upper(s)} 156 ``` 157 158 This expression produces an object whose attributes are the original elements 159 from `var.list` and their corresponding values are the uppercase versions. 160 161 A `for` expression can also include an optional `if` clause to filter elements 162 from the source collection, which can produce a value with fewer elements than 163 the source: 164 165 ```text 166 [for s in var.list : upper(s) if s != ""] 167 ``` 168 169 The source value can also be an object or map value, in which case two 170 temporary variable names can be provided to access the keys and values 171 respectively: 172 173 ```text 174 [for k, v in var.map : length(k) + length(v)] 175 ``` 176 177 Finally, if the result type is an object (using `{` and `}` delimiters) then 178 the value result expression can be followed by the `...` symbol to group 179 together results that have a common key: 180 181 ```text 182 {for s in var.list : substr(s, 0, 1) => s... if s != ""} 183 ``` 184 185 <!--- 186 ## TODO: revamp this section 187 188 ## Splat Expressions 189 190 A _splat expression_ provides a more concise way to express a common operation 191 that could otherwise be performed with a `for` expression. 192 193 If `var.list` is a list of objects that all have an attribute `id`, then a list 194 of the ids could be produced with the following `for` expression: 195 196 ```hcl 197 [for o in var.list : o.id] 198 ``` 199 200 This is equivalent to the following _splat expression:_ 201 202 ```hcl 203 var.list[*].id 204 ``` 205 206 The special `[*]` symbol iterates over all of the elements of the list given to 207 its left and accesses from each one the attribute name given on its right. A 208 splat expression can also be used to access attributes and indexes from lists 209 of complex types by extending the sequence of operations to the right of the 210 symbol: 211 212 ```hcl 213 var.list[*].interfaces[0].name 214 ``` 215 216 The above expression is equivalent to the following `for` expression: 217 218 ```hcl 219 [for o in var.list : o.interfaces[0].name] 220 ``` 221 222 Splat expressions are for lists only (and thus cannot be used [to reference 223 resources created with 224 `for_each`](https://www.terraform.io/docs/configuration/resources.html#referring-to-instances), which 225 are represented as maps). However, if a splat expression is applied to a value 226 that is _not_ a list or tuple then the value is automatically wrapped in a 227 single-element list before processing. 228 229 For example, `var.single_object[*].id` is equivalent to 230 `[var.single_object][*].id`, or effectively `[var.single_object.id]`. This 231 behavior is not interesting in most cases, but it is particularly useful when 232 referring to resources that may or may not have `count` set, and thus may or 233 may not produce a tuple value: 234 235 ```hcl 236 aws_instance.example[*].id 237 ``` 238 239 The above will produce a list of ids whether `aws_instance.example` has `count` 240 set or not, avoiding the need to revise various other expressions in the 241 configuration when a particular resource switches to and from having `count` 242 set. 243 244 ---> 245 246 247 ## `dynamic` blocks 248 249 Within top-level block constructs like sources, expressions can usually be used 250 only when assigning a value to an argument using the `name = expression` or `key = expression` form. This covers many uses, but some source types include 251 repeatable _nested blocks_ in their arguments, which do not accept expressions: 252 253 ```hcl 254 service { 255 port = "db" # can use expressions here 256 257 check { 258 # but the "check" block is always a literal block 259 } 260 } 261 ``` 262 263 You can dynamically construct repeatable nested blocks like `check` using a 264 special `dynamic` block type, which is supported anywhere, example: 265 266 ```hcl 267 locals { 268 check_paths = ["/health", "/"] 269 } 270 271 job "example" { 272 # ... 273 service { 274 port = "lb" # can use expressions here 275 276 dynamic "check" { 277 for_each = local.check_paths 278 279 content { 280 type = "http" 281 port = "lb" 282 path = check.value 283 } 284 } 285 } 286 } 287 ``` 288 289 A `dynamic` block acts much like a `for` expression, but produces nested blocks 290 instead of a complex typed value. It iterates over a given complex value, and 291 generates a nested block for each element of that complex value. 292 293 - The label of the dynamic block (`"check"` in the example above) specifies 294 what kind of nested block to generate. 295 - The `for_each` argument provides the complex value to iterate over. 296 - The `iterator` argument (optional) sets the name of a temporary variable 297 that represents the current element of the complex value. If omitted, the name 298 of the variable defaults to the label of the `dynamic` block (`"check"` in 299 the example above). 300 - The `labels` argument (optional) is a list of strings that specifies the block 301 labels, in order, to use for each generated block. You can use the temporary 302 iterator variable in this value. 303 - The nested `content` block defines the body of each generated block. You can 304 use the temporary iterator variable inside this block. 305 306 Since the `for_each` argument accepts any collection or structural value, 307 you can use a `for` expression or splat expression to transform an existing 308 collection. 309 310 The iterator object (`check` in the example above) has two attributes: 311 312 - `key` is the map key or list element index for the current element. If the 313 `for_each` expression produces a _set_ value then `key` is identical to 314 `value` and should not be used. 315 - `value` is the value of the current element. 316 317 The `for_each` value must be a map or set with one element per desired nested 318 block. If you need to declare resource instances based on a nested data 319 structure or combinations of elements from multiple data structures you can use 320 expressions and functions to derive a suitable value. For some common examples 321 of such situations, see the 322 [`flatten`](/docs/job-specification/hcl2/functions/collection/flatten) and 323 [`setproduct`](/docs/job-specification/hcl2/functions/collection/setproduct) 324 functions. 325 326 ### Best Practices for `dynamic` Blocks 327 328 Overuse of `dynamic` blocks can make configuration hard to read and maintain, 329 so we recommend using them only when you need to hide details in order to build 330 a clean user interface for a re-usable code. Always write nested blocks out 331 literally where possible. 332 333 ## String Literals 334 335 HCL has two different syntaxes for string literals. The 336 most common is to delimit the string with quote characters (`"`), like 337 `"hello"`. In quoted strings, the backslash character serves as an escape 338 sequence, with the following characters selecting the escape behavior: 339 340 | Sequence | Replacement | 341 | ------------ | ----------------------------------------------------------------------------- | 342 | `\n` | Newline | 343 | `\r` | Carriage Return | 344 | `\t` | Tab | 345 | `\"` | Literal quote (without terminating the string) | 346 | `\\` | Literal backslash | 347 | `\uNNNN` | Unicode character from the basic multilingual plane (NNNN is four hex digits) | 348 | `\UNNNNNNNN` | Unicode character from supplementary planes (NNNNNNNN is eight hex digits) | 349 350 The alternative syntax for string literals is the so-called Here Documents or 351 "heredoc" style, inspired by Unix shell languages. This style allows multi-line 352 strings to be expressed more clearly by using a custom delimiter word on a line 353 of its own to close the string: 354 355 ```hcl 356 <<EOF 357 hello 358 world 359 EOF 360 ``` 361 362 The `<<` marker followed by any identifier at the end of a line introduces the 363 sequence. Nomad then processes the following lines until it finds one that 364 consists entirely of the identifier given in the introducer. In the above 365 example, `EOF` is the identifier selected. Any identifier is allowed, but 366 conventionally this identifier is in all-uppercase and begins with `EO`, meaning 367 "end of". `EOF` in this case stands for "end of text". 368 369 The "heredoc" form shown above requires that the lines following be flush with 370 the left margin, which can be awkward when an expression is inside an indented 371 block: 372 373 ```hcl 374 block { 375 value = <<EOF 376 hello 377 world 378 EOF 379 } 380 ``` 381 382 To improve on this, Nomad also accepts an _indented_ heredoc string variant 383 that is introduced by the `<<-` sequence: 384 385 ```hcl 386 block { 387 value = <<-EOF 388 hello 389 world 390 EOF 391 } 392 ``` 393 394 In this case, Nomad analyses the lines in the sequence to find the one 395 with the smallest number of leading spaces, and then trims that many spaces 396 from the beginning of all of the lines, leading to the following result: 397 398 ```text 399 hello 400 world 401 ``` 402 403 Backslash sequences are not interpreted in a heredoc string expression. 404 Instead, the backslash character is interpreted literally. 405 406 In both quoted and heredoc string expressions, Nomad supports template 407 sequences that begin with `${` and `%{`. These are described in more detail 408 in the following section. To include these sequences _literally_ without 409 beginning a template sequence, double the leading character: `$${` or `%%{`. 410 411 ## String Templates 412 413 Within quoted and heredoc string expressions, the sequences `${` and `%{` begin 414 _template sequences_. Templates let you directly embed expressions into a string 415 literal, to dynamically construct strings from other values.