Docs for HCL2 (#9322)

Add more detailed HCL2 docs, mostly lifted from Packer with tweaks for Nomad.

The function docs are basically verbatim taken from Packer with basic string substitutions. I commented out some for_each details as the examples are mostly driven towards Packer resources. I'll iterate on those with better Nomad examples.
This commit is contained in:
Mahmood Ali
2020-11-29 20:36:41 -05:00
committed by GitHub
parent 775465f5c5
commit 15cbc40a70
91 changed files with 5015 additions and 96 deletions

View File

@@ -191,7 +191,146 @@ export default [
{
category: 'job-specification',
content: [
'hcl2',
{
category: 'hcl2',
content: [
'expressions',
{
category: 'functions',
content: [
{
category: 'collection',
name: 'Collection Functions',
content: [
'chunklist',
'coalesce',
'coalescelist',
'compact',
'concat',
'contains',
'distinct',
'element',
'flatten',
'index-fn',
'keys',
'length',
'lookup',
'merge',
'range',
'reverse',
'setintersection',
'setproduct',
'setunion',
'slice',
'sort',
'values',
'zipmap',
],
},
{
category: 'conversion',
name: 'Type Conversion Functions',
content: ['can', 'convert', 'try'],
},
{
category: 'crypto',
name: 'Hash and Crypto Functions',
content: [
'bcrypt',
'md5',
'rsadecrypt',
'sha1',
'sha256',
'sha512',
],
},
{
category: 'datetime',
name: 'Date and Time Functions',
content: ['formatdate', 'timeadd', 'timestamp'],
},
{
category: 'encoding',
name: 'Encoding Functions',
content: [
'base64decode',
'base64encode',
'csvdecode',
'jsondecode',
'jsonencode',
'urlencode',
'yamldecode',
'yamlencode',
],
},
{
category: 'file',
name: 'Filesystem Functions',
content: [
'abspath',
'basename',
'dirname',
'file',
'fileexists',
'fileset',
'pathexpand',
],
},
{
category: 'ipnet',
name: 'IP Network Functions',
content: ['cidrhost', 'cidrnetmask', 'cidrsubnet', 'cidrsubnets'],
},
{
category: 'numeric',
name: 'Numeric Functions',
content: [
'abs',
'ceil',
'floor',
'log',
'max',
'min',
'parseint',
'pow',
'signum',
],
},
{
category: 'string',
name: 'String Functions',
content: [
'chomp',
'format',
'formatlist',
'indent',
'join',
'lower',
'regex_replace',
'replace',
'split',
'strrev',
'substr',
'title',
'trim',
'trimprefix',
'trimspace',
'trimsuffix',
'upper',
],
},
{
category: 'uuid',
name: 'UUID Functions',
content: ['uuidv4', 'uuidv5'],
},
],
},
'locals',
'syntax',
'variables',
],
},
'artifact',
'affinity',
'check_restart',

View File

@@ -1,95 +0,0 @@
---
layout: docs
page_title: HCL2
sidebar_title: HCL2 <sup>Beta</sup>
description: Learn about the Job specification HCL2 used to submit jobs to Nomad.
---
# HCL2 <sup>Beta</sup>
~> **NOTE:** This page is about Nomad 1.0 Beta. Details are subject to change before final release.
Nomad 1.0 adopts
[HCL2](https://github.com/hashicorp/hcl2/blob/master/README.md), the second
generation of HashiCorp Configuration Language. HCL2 extends the HCL language by
adding expressions and input variables support to improve job spec
reusability and readability. Also, the new HCL2 parser improves the error
messages for invalid jobs.
## Expressions
Nomad 1.0 supports expressions and built-in functions, allowing for a more concise job spec. HCL2 allows use of the following expressions:
- value literals: e.g. `42`, `"hello"`, `true`
- arithmetic expression: `5*100`
- for-each expressions: `[for s in [3, 4, 5]: s+1]` (which evaluates to `[4, 5, 6]`)
- invocation of function calls: `upper("FOO")`.
For a full list of available functions, see [the function reference](https://www.packer.io/docs/from-1.5/functions).
The following snippet illustrates the power of expressions and built-in functions:
```hcl
template {
# `file` function can load external files without embedding them in the jobspec file
data = file("scripts.sh")
destination = "local/scripts.sh"
}
template {
# jsonencode eases maintaining json field
data = jsonencode({ regions = { tokyo = 4, mumbai = 2, us_east = 3 }})
destination = "local/region_mapping.json"
}
resources {
# arithmetics can make values more obvious
memory = 2 * 1014
}
```
## Input Variables
Input variables serve as parameters for Nomad jobs, allowing reuse of the job spec
to target multiple environments or contexts without altering the job spec source.
Input variables don't need to be explicitly declared, and can be referenced
within expressions as `vars.<NAME>`. You can set the variable in the CLI by
passing `-var <NAME>=<VALUE>`.
For example, to repurpose the job spec to target different environments (e.g.
staging vs production), you can use `vars.environment` in the job spec, and pass
`--var environment=production`.
## Backward Compatibilities
HCL2 syntax closely mirrors HCL1, but has some minor changes. Most existing
Nomad job specifications will not require any changes.
When you run `nomad job run` or `nomad job plan`, the CLI will report any
required changes. Also, you can activate a backwards compatibility mode by
passing `-hcl1` to use Nomad's HCL1 parser instead.
### Blocks
Nomad 0.12 and earlier allowed a few variations for defining blocks. For example, the following variations of `meta` were accepted:
```hcl
meta {
# meta attributes can be quoted or not
"team" = "..."
organization = "..."
}
# meta can be an assignment to a map
meta = { "team" = "...", organization = "..." }
```
Starting with Nomad 1.0 and the HCL2 parser, only the block syntax with unquoted attributes is accepted:
```hcl
meta {
team = "..."
organization = "..."
}
```

View File

@@ -0,0 +1,415 @@
---
layout: docs
page_title: Expressions - Configuration Language
sidebar_title: Expressions
description: |-
HCL allows the use of expressions to access data exported
by sources and to transform and combine that data to produce other values.
---
# Expressions
`@include 'beta-nomad1.0-note.mdx'`
_Expressions_ are used to refer to or compute values within a configuration.
The simplest expressions are just literal values, like `"hello"` or `5`, but
HCL also allows more complex expressions such as arithmetic, conditional
evaluation, and a number of built-in functions.
Expressions can be used in a number of places in HCL, but some contexts limit
which expression constructs are allowed, such as requiring a literal value of a
particular type or forbidding. Each language feature's documentation describes
any restrictions it places on expressions.
The rest of this page describes all of the features of Nomad's
expression syntax.
## Types and Values
The result of an expression is a _value_. All values have a _type_, which
dictates where that value can be used and what transformations can be
applied to it.
HCL uses the following types for its values:
- `string`: a sequence of Unicode characters representing some text, like
`"hello"`.
- `number`: a numeric value. The `number` type can represent both whole
numbers like `15` and fractional values like `6.283185`.
- `bool`: either `true` or `false`. `bool` values can be used in conditional
logic.
- `list` (or `tuple`): a sequence of values, like
`["us-west-1a", "us-west-1c"]`. Elements in a list or tuple are identified by
consecutive whole numbers, starting with zero.
- `map` (or `object`): a group of values identified by named labels, like
`{name = "Mabel", age = 52}`.
Strings, numbers, and bools are sometimes called _primitive types._
Lists/tuples and maps/objects are sometimes called _complex types,_ _structural
types,_ or _collection types._
Finally, there is one special value that has _no_ type:
- `null`: a value that represents _absence_ or _omission._ If you set an
argument to `null`, Nomad behaves as though you
had completely omitted it — it will use the argument's default value if it has
one, or raise an error if the argument is mandatory. `null` is most useful in
conditional expressions, so you can dynamically omit an argument if a
condition isn't met.
### Advanced Type Details
In most situations, lists and tuples behave identically, as do maps and objects.
Whenever the distinction isn't relevant, the Nomad documentation uses each
pair of terms interchangeably (with a historical preference for "list" and
"map").
### Type Conversion
Expressions are most often used to set values for arguments. In these cases,
the argument has an expected type and the given expression must produce a value
of that type.
Where possible, Nomad automatically converts values from one type to
another in order to produce the expected type. If this isn't possible, Nomad
will produce a type mismatch error and you must update the configuration with a
more suitable expression.
Nomad automatically converts number and bool values to strings when needed.
It also converts strings to numbers or bools, as long as the string contains a
valid representation of a number or bool value.
- `true` converts to `"true"`, and vice-versa
- `false` converts to `"false"`, and vice-versa
- `15` converts to `"15"`, and vice-versa
## Literal Expressions
A _literal expression_ is an expression that directly represents a particular
constant value. Nomad has a literal expression syntax for each of the value
types described above:
- Strings are usually represented by a double-quoted sequence of Unicode
characters, `"like this"`. There is also a "heredoc" syntax for more complex
strings. String literals are the most complex kind of literal expression in
Nomad, and have additional documentation on this page:
- See [String Literals](#string-literals) below for information about escape
sequences and the heredoc syntax.
- See [String Templates](#string-templates) below for information about
interpolation and template directives.
- Numbers are represented by unquoted sequences of digits with or without a
decimal point, like `15` or `6.283185`.
- Bools are represented by the unquoted symbols `true` and `false`.
- The null value is represented by the unquoted symbol `null`.
- Lists/tuples are represented by a pair of square brackets containing a
comma-separated sequence of values, like `["a", 15, true]`.
List literals can be split into multiple lines for readability, but always
require a comma between values. A comma after the final value is allowed,
but not required. Values in a list can be arbitrary expressions.
- Maps/objects are represented by a pair of curly braces containing a series of
`<KEY> = <VALUE>` pairs:
```hcl
{
name = "John"
age = 52
}
```
Key/value pairs can be separated by either a comma or a line break. Values
can be arbitrary expressions. Keys are strings; they can be left unquoted if
they are a valid [identifier](/docs/job-specification/hcl2/syntax#identifiers), but must be quoted
otherwise. You can use a non-literal expression as a key by wrapping it in
parentheses, like `(var.business_unit_tag_name) = "SRE"`.
### Available Functions
For a full list of available functions, see [the function
reference](/docs/job-specification/hcl2/functions).
## `for` Expressions
A _`for` expression_ creates a complex type value by transforming
another complex type value. Each element in the input value
can correspond to either one or zero values in the result, and an arbitrary
expression can be used to transform each input element into an output element.
For example, if `var.list` is a list of strings, then the following expression
produces a list of strings with all-uppercase letters:
```hcl
[for s in var.list : upper(s)]
```
This `for` expression iterates over each element of `var.list`, and then
evaluates the expression `upper(s)` with `s` set to each respective element.
It then builds a new tuple value with all of the results of executing that
expression in the same order.
The type of brackets around the `for` expression decide what type of result
it produces. The above example uses `[` and `]`, which produces a tuple. If
`{` and `}` are used instead, the result is an object, and two result
expressions must be provided separated by the `=>` symbol:
```hcl
{for s in var.list : s => upper(s)}
```
This expression produces an object whose attributes are the original elements
from `var.list` and their corresponding values are the uppercase versions.
A `for` expression can also include an optional `if` clause to filter elements
from the source collection, which can produce a value with fewer elements than
the source:
```text
[for s in var.list : upper(s) if s != ""]
```
The source value can also be an object or map value, in which case two
temporary variable names can be provided to access the keys and values
respectively:
```text
[for k, v in var.map : length(k) + length(v)]
```
Finally, if the result type is an object (using `{` and `}` delimiters) then
the value result expression can be followed by the `...` symbol to group
together results that have a common key:
```text
{for s in var.list : substr(s, 0, 1) => s... if s != ""}
```
<!---
## TODO: revamp this section
## Splat Expressions
A _splat expression_ provides a more concise way to express a common operation
that could otherwise be performed with a `for` expression.
If `var.list` is a list of objects that all have an attribute `id`, then a list
of the ids could be produced with the following `for` expression:
```hcl
[for o in var.list : o.id]
```
This is equivalent to the following _splat expression:_
```hcl
var.list[*].id
```
The special `[*]` symbol iterates over all of the elements of the list given to
its left and accesses from each one the attribute name given on its right. A
splat expression can also be used to access attributes and indexes from lists
of complex types by extending the sequence of operations to the right of the
symbol:
```hcl
var.list[*].interfaces[0].name
```
The above expression is equivalent to the following `for` expression:
```hcl
[for o in var.list : o.interfaces[0].name]
```
Splat expressions are for lists only (and thus cannot be used [to reference
resources created with
`for_each`](https://www.terraform.io/docs/configuration/resources.html#referring-to-instances), which
are represented as maps). However, if a splat expression is applied to a value
that is _not_ a list or tuple then the value is automatically wrapped in a
single-element list before processing.
For example, `var.single_object[*].id` is equivalent to
`[var.single_object][*].id`, or effectively `[var.single_object.id]`. This
behavior is not interesting in most cases, but it is particularly useful when
referring to resources that may or may not have `count` set, and thus may or
may not produce a tuple value:
```hcl
aws_instance.example[*].id
```
The above will produce a list of ids whether `aws_instance.example` has `count`
set or not, avoiding the need to revise various other expressions in the
configuration when a particular resource switches to and from having `count`
set.
--->
## `dynamic` blocks
Within top-level block constructs like sources, expressions can usually be used
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
repeatable _nested blocks_ in their arguments, which do not accept expressions:
```hcl
service {
port = "db" # can use expressions here
check {
# but the "check" block is always a literal block
}
}
```
You can dynamically construct repeatable nested blocks like `check` using a
special `dynamic` block type, which is supported anywhere, example:
```hcl
locals {
check_paths = ["/health", "/"]
}
job "example" {
# ...
service {
port = "lb" # can use expressions here
dynamic "check" {
for_each = local.check_paths
content {
type = "http"
port = "lb"
path = check.value
}
}
}
}
```
A `dynamic` block acts much like a `for` expression, but produces nested blocks
instead of a complex typed value. It iterates over a given complex value, and
generates a nested block for each element of that complex value.
- The label of the dynamic block (`"check"` in the example above) specifies
what kind of nested block to generate.
- The `for_each` argument provides the complex value to iterate over.
- The `iterator` argument (optional) sets the name of a temporary variable
that represents the current element of the complex value. If omitted, the name
of the variable defaults to the label of the `dynamic` block (`"check"` in
the example above).
- The `labels` argument (optional) is a list of strings that specifies the block
labels, in order, to use for each generated block. You can use the temporary
iterator variable in this value.
- The nested `content` block defines the body of each generated block. You can
use the temporary iterator variable inside this block.
Since the `for_each` argument accepts any collection or structural value,
you can use a `for` expression or splat expression to transform an existing
collection.
The iterator object (`check` in the example above) has two attributes:
- `key` is the map key or list element index for the current element. If the
`for_each` expression produces a _set_ value then `key` is identical to
`value` and should not be used.
- `value` is the value of the current element.
The `for_each` value must be a map or set with one element per desired nested
block. If you need to declare resource instances based on a nested data
structure or combinations of elements from multiple data structures you can use
expressions and functions to derive a suitable value. For some common examples
of such situations, see the
[`flatten`](/docs/job-specification/hcl2/functions/collection/flatten) and
[`setproduct`](/docs/job-specification/hcl2/functions/collection/setproduct)
functions.
### Best Practices for `dynamic` Blocks
Overuse of `dynamic` blocks can make configuration hard to read and maintain,
so we recommend using them only when you need to hide details in order to build
a clean user interface for a re-usable code. Always write nested blocks out
literally where possible.
## String Literals
HCL has two different syntaxes for string literals. The
most common is to delimit the string with quote characters (`"`), like
`"hello"`. In quoted strings, the backslash character serves as an escape
sequence, with the following characters selecting the escape behavior:
| Sequence | Replacement |
| ------------ | ----------------------------------------------------------------------------- |
| `\n` | Newline |
| `\r` | Carriage Return |
| `\t` | Tab |
| `\"` | Literal quote (without terminating the string) |
| `\\` | Literal backslash |
| `\uNNNN` | Unicode character from the basic multilingual plane (NNNN is four hex digits) |
| `\UNNNNNNNN` | Unicode character from supplementary planes (NNNNNNNN is eight hex digits) |
The alternative syntax for string literals is the so-called Here Documents or
"heredoc" style, inspired by Unix shell languages. This style allows multi-line
strings to be expressed more clearly by using a custom delimiter word on a line
of its own to close the string:
```hcl
<<EOF
hello
world
EOF
```
The `<<` marker followed by any identifier at the end of a line introduces the
sequence. Nomad then processes the following lines until it finds one that
consists entirely of the identifier given in the introducer. In the above
example, `EOF` is the identifier selected. Any identifier is allowed, but
conventionally this identifier is in all-uppercase and begins with `EO`, meaning
"end of". `EOF` in this case stands for "end of text".
The "heredoc" form shown above requires that the lines following be flush with
the left margin, which can be awkward when an expression is inside an indented
block:
```hcl
block {
value = <<EOF
hello
world
EOF
}
```
To improve on this, Nomad also accepts an _indented_ heredoc string variant
that is introduced by the `<<-` sequence:
```hcl
block {
value = <<-EOF
hello
world
EOF
}
```
In this case, Nomad analyses the lines in the sequence to find the one
with the smallest number of leading spaces, and then trims that many spaces
from the beginning of all of the lines, leading to the following result:
```text
hello
world
```
Backslash sequences are not interpreted in a heredoc string expression.
Instead, the backslash character is interpreted literally.
In both quoted and heredoc string expressions, Nomad supports template
sequences that begin with `${` and `%{`. These are described in more detail
in the following section. To include these sequences _literally_ without
beginning a template sequence, double the leading character: `$${` or `%%{`.
## String Templates
Within quoted and heredoc string expressions, the sequences `${` and `%{` begin
_template sequences_. Templates let you directly embed expressions into a string
literal, to dynamically construct strings from other values.

View File

@@ -0,0 +1,36 @@
---
layout: docs
page_title: chunklist - Functions - Configuration Language
sidebar_title: chunklist
description: |-
The chunklist function splits a single list into fixed-size chunks, returning
a list of lists.
---
# `chunklist` Function
`chunklist` splits a single list into fixed-size chunks, returning a list
of lists.
```hcl
chunklist(list, chunk_size)
```
## Examples
```shell-session
> chunklist(["a", "b", "c", "d", "e"], 2)
[
["a", "b"],
["c", "d"],
["e"]
]
> chunklist(["a", "b", "c", "d", "e"], 1)
[
["a"],
["b"],
["c"],
["d"],
["e"]
]
```

View File

@@ -0,0 +1,37 @@
---
layout: docs
page_title: coalesce - Functions - Configuration Language
sidebar_title: coalesce
description: |-
The coalesce function takes any number of arguments and returns the
first one that isn't null nor empty.
---
# `coalesce` Function
`coalesce` takes any number of arguments and returns the first one
that isn't null or an empty string.
## Examples
```shell-session
> coalesce("a", "b")
a
> coalesce("", "b")
b
> coalesce(1,2)
1
```
To perform the `coalesce` operation with a list of strings, use the `...`
symbol to expand the list as arguments:
```shell-session
> coalesce(["", "b"]...)
b
```
## Related Functions
- [`coalescelist`](/docs/job-specification/hcl2/functions/collection/coalescelist) performs a similar operation with
list arguments rather than individual arguments.

View File

@@ -0,0 +1,44 @@
---
layout: docs
page_title: coalescelist - Functions - Configuration Language
sidebar_title: coalescelist
description: |-
The coalescelist function takes any number of list arguments and returns the
first one that isn't empty.
---
# `coalescelist` Function
`coalescelist` takes any number of list arguments and returns the first one
that isn't empty.
## Examples
```shell-session
> coalescelist(["a", "b"], ["c", "d"])
[
"a",
"b",
]
> coalescelist([], ["c", "d"])
[
"c",
"d",
]
```
To perform the `coalescelist` operation with a list of lists, use the `...`
symbol to expand the outer list as arguments:
```shell-session
> coalescelist([[], ["c", "d"]]...)
[
"c",
"d",
]
```
## Related Functions
- [`coalesce`](/docs/job-specification/hcl2/functions/collection/coalesce) performs a similar operation with string
arguments rather than list arguments.

View File

@@ -0,0 +1,22 @@
---
layout: docs
page_title: compact - Functions - Configuration Language
sidebar_title: compact
description: The compact function removes empty string elements from a list.
---
# `compact` Function
`compact` takes a list of strings and returns a new list with any empty string
elements removed.
## Examples
```shell-session
> compact(["a", "", "b", "c"])
[
"a",
"b",
"c",
]
```

View File

@@ -0,0 +1,22 @@
---
layout: docs
page_title: concat - Functions - Configuration Language
sidebar_title: concat
description: The concat function combines two or more lists into a single list.
---
# `concat` Function
`concat` takes two or more lists and combines them into a single list.
## Examples
```shell-session
> concat(["a", ""], ["b", "c"])
[
"a",
"",
"b",
"c",
]
```

View File

@@ -0,0 +1,24 @@
---
layout: docs
page_title: contains - Functions - Configuration Language
sidebar_title: contains
description: The contains function determines whether a list or set contains a given value.
---
# `contains` Function
`contains` determines whether a given list or set contains a given single value
as one of its elements.
```hcl
contains(list, value)
```
## Examples
```shell-session
> contains(["a", "b", "c"], "a")
true
> contains(["a", "b", "c"], "d")
false
```

View File

@@ -0,0 +1,26 @@
---
layout: docs
page_title: distinct - Functions - Configuration Language
sidebar_title: distinct
description: The distinct function removes duplicate elements from a list.
---
# `distinct` Function
`distinct` takes a list and returns a new list with any duplicate elements
removed.
The first occurrence of each value is retained and the relative ordering of
these elements is preserved.
## Examples
```shell-session
> distinct(["a", "b", "a", "c", "d", "b"])
[
"a",
"b",
"c",
"d",
]
```

View File

@@ -0,0 +1,40 @@
---
layout: docs
page_title: element - Functions - Configuration Language
sidebar_title: element
description: The element function retrieves a single element from a list.
---
# `element` Function
`element` retrieves a single element from a list.
```hcl
element(list, index)
```
The index is zero-based. This function produces an error if used with an
empty list.
Use the built-in index syntax `list[index]` in most cases. Use this function
only for the special additional "wrap-around" behavior described below.
## Examples
```shell-session
> element(["a", "b", "c"], 1)
b
```
If the given index is greater than the length of the list then the index is
"wrapped around" by taking the index modulo the length of the list:
```shell-session
> element(["a", "b", "c"], 3)
a
```
## Related Functions
- [`index`](/docs/job-specification/hcl2/functions/collection/index-fn) finds the index for a particular element value.
- [`lookup`](/docs/job-specification/hcl2/functions/collection/lookup) retrieves a value from a _map_ given its _key_.

View File

@@ -0,0 +1,116 @@
---
layout: docs
page_title: flatten - Functions - Configuration Language
sidebar_title: flatten
description: The flatten function eliminates nested lists from a list.
---
# `flatten` Function
`flatten` takes a list and replaces any elements that are lists with a
flattened sequence of the list contents.
## Examples
```shell-session
> flatten([["a", "b"], [], ["c"]])
["a", "b", "c"]
```
If any of the nested lists also contain directly-nested lists, these too are
flattened recursively:
```shell-session
> flatten([[["a", "b"], []], ["c"]])
["a", "b", "c"]
```
Indirectly-nested lists, such as those in maps, are _not_ flattened.
<!---
## TODO: revamp this section
## Flattening nested structures for `for_each`
The
[resource `for_each`](https://www.terraform.io/docs/configuration/resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings)
and
[`dynamic` block](/docs/job-specification/hcl2/expressions#dynamic-blocks)
language features both require a collection value that has one element for
each repetition.
Sometimes your input data structure isn't naturally in a suitable shape for
use in a `for_each` argument, and `flatten` can be a useful helper function
when reducing a nested data structure into a flat one.
For example, consider a folder that declares a variable like the following:
```hcl
variable "networks" {
type = map(object({
cidr_block = string
subnets = map(object({
cidr_block = string
})
})
}
```
The above is a reasonable way to model objects that naturally form a tree,
such as top-level networks and their subnets. The repetition for the top-level
networks can use this variable directly, because it's already in a form
where the resulting instances match one-to-one with map elements:
```hcl
resource "aws_vpc" "example" {
for_each = var.networks
cidr_block = each.value.cidr_block
}
```
However, in order to declare all of the _subnets_ with a single `resource`
block, we must first flatten the structure to produce a collection where each
top-level element represents a single subnet:
```hcl
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
network_subnets = flatten([
for network_key, network in var.networks : [
for subnet_key, subnet in network.subnets : {
network_key = network_key
subnet_key = subnet_key
network_id = aws_vpc.example[network_key].id
cidr_block = subnet.cidr_block
}
]
])
}
resource "aws_subnet" "example" {
# local.network_subnets is a list, so we must now project it into a map
# where each key is unique. We'll combine the network and subnet keys to
# produce a single unique key per instance.
for_each = {
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
}
vpc_id = each.value.network_id
availability_zone = each.value.subnet_key
cidr_block = each.value_cidr_block
}
```
The above results in one subnet instance per subnet object, while retaining
the associations between the subnets and their containing networks.
-->
## Related Functions
- [`setproduct`](/docs/job-specification/hcl2/functions/collection/setproduct) finds all of the combinations of multiple
lists or sets of values, which can also be useful when preparing collections
for use with `for_each` constructs.

View File

@@ -0,0 +1,29 @@
---
layout: docs
page_title: index - Functions - Configuration Language
sidebar_title: index
description: The index function finds the element index for a given value in a list.
---
# `index` Function
`index` finds the element index for a given value in a list.
```hcl
index(list, value)
```
The returned index is zero-based. This function produces an error if the given
value is not present in the list.
## Examples
```shell-session
> index(["a", "b", "c"], "b")
1
```
## Related Functions
- [`element`](/docs/job-specification/hcl2/functions/collection/element) retrieves a particular element from a list given
its index.

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: keys - Functions - Configuration Language
sidebar_title: keys
description: The keys function returns a list of the keys in a given map.
---
# `keys` Function
`keys` takes a map and returns a list containing the keys from that map.
The keys are returned in lexicographical order, ensuring that the result will
be identical as long as the keys in the map don't change.
## Examples
```shell-session
> keys({a=1, c=2, d=3})
[
"a",
"c",
"d",
]
```
## Related Functions
- [`values`](/docs/job-specification/hcl2/functions/collection/values) returns a list of the _values_ from a map.

View File

@@ -0,0 +1,41 @@
---
layout: docs
page_title: length - Functions - Configuration Language
sidebar_title: length
description: The length function determines the length of a collection or string.
---
# `length` Function
`length` determines the length of a given list, map, or string.
If given a list or map, the result is the number of elements in that collection.
If given a string, the result is the number of characters in the string.
## Examples
```shell-session
> length([])
0
> length(["a", "b"])
2
> length({"a" = "b"})
1
> length("hello")
5
```
When given a string, the result is the number of characters, rather than the
number of bytes or Unicode sequences that form them:
```shell-session
> length("👾🕹️")
2
```
A "character" is a _grapheme cluster_, as defined by
[Unicode Standard Annex #29](http://unicode.org/reports/tr29/). Note that
remote APIs may have a different definition of "character" for the purpose of
length limits on string arguments; a Nomad provider is responsible for
translating Nomad's string representation into that used by its respective
remote system and applying any additional validation rules to it.

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: lookup - Functions - Configuration Language
sidebar_title: lookup
description: The lookup function retrieves an element value from a map given its key.
---
# `lookup` Function
`lookup` retrieves the value of a single element from a map, given its key.
If the given key does not exist, a the given default value is returned instead.
```hcl
lookup(map, key, default)
```
## Examples
```shell-session
> lookup({a="ay", b="bee"}, "a", "what?")
ay
> lookup({a="ay", b="bee"}, "c", "what?")
what?
```
## Related Functions
- [`element`](/docs/job-specification/hcl2/functions/collection/element) retrieves a value from a _list_ given its _index_.

View File

@@ -0,0 +1,27 @@
---
layout: docs
page_title: merge - Functions - Configuration Language
sidebar_title: merge
description: |-
The merge function takes an arbitrary number of maps and returns a single
map after merging the keys from each argument.
---
# `merge` Function
`merge` takes an arbitrary number of maps and returns a single map that
contains a merged set of elements from all of the maps.
If more than one given map defines the same key then the one that is later
in the argument sequence takes precedence.
## Examples
```shell-session
> merge({"a"="b", "c"="d"}, {"e"="f", "c"="z"})
{
"a" = "b"
"c" = "z"
"e" = "f"
}
```

View File

@@ -0,0 +1,141 @@
---
layout: docs
page_title: range - Functions - Configuration Language
sidebar_title: range
description: The range function generates sequences of numbers.
---
# `range` Function
`range` generates a list of numbers using a start value, a limit value,
and a step value.
```hcl
range(max)
range(start, limit)
range(start, limit, step)
```
The `start` and `step` arguments can be omitted, in which case `start` defaults
to zero and `step` defaults to either one or negative one depending on whether
`limit` is greater than or less than `start`.
The resulting list is created by starting with the given `start` value and
repeatedly adding `step` to it until the result is equal to or beyond `limit`.
The interpretation of `limit` depends on the direction of `step`: for a positive
step, the sequence is complete when the next number is greater than or equal
to `limit`. For a negative step, it's complete when less than or equal.
The sequence-building algorithm follows the following pseudocode:
```text
let num = start
while num < limit: (or, for negative step, num >= limit)
append num to the sequence
num = num + step
return the sequence
```
Because the sequence is created as a physical list in memory, Nomad imposes
an artificial limit of 1024 numbers in the resulting sequence in order to avoid
unbounded memory usage if, for example, a very large value were accidentally
passed as the limit or a very small value as the step. If the algorithm above
would append the 1025th number to the sequence, the function immediately exits
with an error.
We recommend iterating over existing collections where possible, rather than
creating ranges. However, creating small numerical sequences can sometimes
be useful when combined with other collections in collection-manipulation
functions or `for` expressions.
## Examples
```shell-session
> range(3)
[
0,
1,
2,
]
> range(1, 4)
[
1,
2,
3,
]
> range(1, 8, 2)
[
1,
3,
5,
7,
]
> range(1, 4, 0.5)
[
1,
1.5,
2,
2.5,
3,
3.5,
]
> range(4, 1)
[
4,
3,
2,
]
> range(10, 5, -2)
[
10,
8,
6,
]
```
The `range` function is primarily useful when working with other collections
to produce a certain number of instances of something. For example:
```hcl
variable "name_counts" {
type = map(number)
default = {
"foo" = 2
"bar" = 4
}
}
locals {
expanded_names = {
for name, count in var.name_counts : name => [
for i in range(count) : format("%s%02d", name, i)
]
}
}
output "expanded_names" {
value = local.expanded_names
}
# Produces the following expanded_names value when run with the default
# "name_counts":
#
# {
# "bar" = [
# "bar00",
# "bar01",
# "bar02",
# "bar03",
# ]
# "foo" = [
# "foo00",
# "foo01",
# ]
# }
```

View File

@@ -0,0 +1,26 @@
---
layout: docs
page_title: reverse - Functions - Configuration Language
sidebar_title: reverse
description: The reverse function reverses a sequence.
---
# `reverse` Function
`reverse` takes a sequence and produces a new sequence of the same length
with all of the same elements as the given sequence but in reverse order.
## Examples
```shell-session
> reverse([1, 2, 3])
[
3,
2,
1,
]
```
## Related Functions
- [`strrev`](/docs/job-specification/hcl2/functions/string/strrev) reverses a string.

View File

@@ -0,0 +1,40 @@
---
layout: docs
page_title: setintersection - Functions - Configuration Language
sidebar_title: setintersection
description: |-
The setintersection function takes multiple sets and produces a single set
containing only the elements that all of the given sets have in common.
---
# `setintersection` Function
The `setintersection` function takes multiple sets and produces a single set
containing only the elements that all of the given sets have in common.
In other words, it computes the
[intersection](<https://en.wikipedia.org/wiki/Intersection_(set_theory)>) of the sets.
```hcl
setintersection(sets...)
```
## Examples
```shell-session
> setintersection(["a", "b"], ["b", "c"], ["b", "d"])
[
"b",
]
```
The given arguments are converted to sets, so the result is also a set and
the ordering of the given elements is not preserved.
## Related Functions
- [`contains`](/docs/job-specification/hcl2/functions/collection/contains) tests whether a given list or set contains
a given element value.
- [`setproduct`](/docs/job-specification/hcl2/functions/collection/setproduct) computes the _Cartesian product_ of multiple
sets.
- [`setunion`](/docs/job-specification/hcl2/functions/collection/setunion) computes the _union_ of
multiple sets.

View File

@@ -0,0 +1,230 @@
---
layout: docs
page_title: setproduct - Functions - Configuration Language
sidebar_title: setproduct
description: |-
The setproduct function finds all of the possible combinations of elements
from all of the given sets by computing the cartesian product.
---
# `setproduct` Function
The `setproduct` function finds all of the possible combinations of elements
from all of the given sets by computing the
[Cartesian product](https://en.wikipedia.org/wiki/Cartesian_product).
```hcl
setproduct(sets...)
```
This function is particularly useful for finding the exhaustive set of all
combinations of members of multiple sets, such as per-application-per-environment
resources.
```shell-session
> setproduct(["development", "staging", "production"], ["app1", "app2"])
[
[
"development",
"app1",
],
[
"development",
"app2",
],
[
"staging",
"app1",
],
[
"staging",
"app2",
],
[
"production",
"app1",
],
[
"production",
"app2",
],
]
```
You must past at least two arguments to this function.
Although defined primarily for sets, this function can also work with lists.
If all of the given arguments are lists then the result is a list, preserving
the ordering of the given lists. Otherwise the result is a set. In either case,
the result's element type is a list of values corresponding to each given
argument in turn.
## Examples
There is an example of the common usage of this function above. There are some
other situations that are less common when hand-writing but may arise in
reusable folder situations.
If any of the arguments is empty then the result is always empty itself,
similar to how multiplying any number by zero gives zero:
```shell-session
> setproduct(["development", "staging", "production"], [])
[]
```
Similarly, if all of the arguments have only one element then the result has
only one element, which is the first element of each argument:
```shell-session
> setproduct(["a"], ["b"])
[
[
"a",
"b",
],
]
```
Each argument must have a consistent type for all of its elements. If not,
Nomad will attempt to convert to the most general type, or produce an
error if such a conversion is impossible. For example, mixing both strings and
numbers results in the numbers being converted to strings so that the result
elements all have a consistent type:
```shell-session
> setproduct(["staging", "production"], ["a", 2])
[
[
"staging",
"a",
],
[
"staging",
"2",
],
[
"production",
"a",
],
[
"production",
"2",
],
]
```
<!---
## TODO: Revamp this section
## Finding combinations for `for_each`
The
[resource `for_each`](https://www.terraform.io/docs/configuration/resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings)
and
[`dynamic` block](/docs/job-specification/hcl2/expressions/#dynamic-blocks)
language features both require a collection value that has one element for
each repetition.
Sometimes your input data comes in separate values that cannot be directly
used in a `for_each` argument, and `setproduct` can be a useful helper function
for the situation where you want to find all unique combinations of elements in
a number of different collections.
For example, consider a folder that declares variables like the following:
```hcl
variable "networks" {
type = map(object({
base_cidr_block = string
}))
}
variable "subnets" {
type = map(object({
number = number
}))
}
```
If the goal is to create each of the defined subnets per each of the defined
networks, creating the top-level networks can directly use `var.networks`
because it's already in a form where the resulting instances match one-to-one
with map elements:
```hcl
resource "aws_vpc" "example" {
for_each = var.networks
cidr_block = each.value.base_cidr_block
}
```
However, in order to declare all of the _subnets_ with a single `resource`
block, we must first produce a collection whose elements represent all of
the combinations of networks and subnets, so that each element itself
represents a subnet:
```hcl
locals {
# setproduct works with sets and lists, but our variables are both maps
# so we'll need to convert them first.
networks = [
for key, network in var.networks : {
key = key
cidr_block = network.cidr_block
}
]
subnets = [
for key, subnet in var.subnets : {
key = key
number = subnet.number
}
]
network_subnets = [
# in pair, element zero is a network and element one is a subnet,
# in all unique combinations.
for pair in setproduct(local.networks, local.subnets) : {
network_key = pair[0].key
subnet_key = pair[1].key
network_id = aws_vpc.example[pair[0].key].id
# The cidr_block is derived from the corresponding network. See the
# cidrsubnet function for more information on how this calculation works.
cidr_block = cidrsubnet(pair[0].cidr_block, 4, pair[1].number)
}
]
}
resource "aws_subnet" "example" {
# local.network_subnets is a list, so we must now project it into a map
# where each key is unique. We'll combine the network and subnet keys to
# produce a single unique key per instance.
for_each = {
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
}
vpc_id = each.value.network_id
availability_zone = each.value.subnet_key
cidr_block = each.value_cidr_block
}
```
The above results in one subnet instance per combination of network and subnet
elements in the input variables.
-->
## Related Functions
- [`contains`](/docs/job-specification/hcl2/functions/collection/contains) tests whether a given list or set contains
a given element value.
- [`flatten`](/docs/job-specification/hcl2/functions/collection/flatten) is useful for flattening heirarchical data
into a single list, for situations where the relationships between two
object types are defined explicitly.
- [`setintersection`](/docs/job-specification/hcl2/functions/collection/setintersection) computes the _intersection_ of
multiple sets.
- [`setunion`](/docs/job-specification/hcl2/functions/collection/setunion) computes the _union_ of multiple
sets.

View File

@@ -0,0 +1,43 @@
---
layout: docs
page_title: setunion - Functions - Configuration Language
sidebar_title: setunion
description: |-
The setunion function takes multiple sets and produces a single set
containing the elements from all of the given sets.
---
# `setunion` Function
The `setunion` function takes multiple sets and produces a single set
containing the elements from all of the given sets. In other words, it
computes the [union](<https://en.wikipedia.org/wiki/Union_(set_theory)>) of
the sets.
```hcl
setunion(sets...)
```
## Examples
```shell-session
> setunion(["a", "b"], ["b", "c"], ["d"])
[
"d",
"b",
"c",
"a",
]
```
The given arguments are converted to sets, so the result is also a set and
the ordering of the given elements is not preserved.
## Related Functions
- [`contains`](/docs/job-specification/hcl2/functions/collection/contains) tests whether a given list or set contains
a given element value.
- [`setintersection`](/docs/job-specification/hcl2/functions/collection/setintersection) computes the _intersection_ of
multiple sets.
- [`setproduct`](/docs/job-specification/hcl2/functions/collection/setproduct) computes the _Cartesian product_ of multiple
sets.

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: slice - Functions - Configuration Language
sidebar_title: slice
description: The slice function extracts some consecutive elements from within a list.
---
# `slice` Function
`slice` extracts some consecutive elements from within a list.
```hcl
slice(list, startindex, endindex)
```
`startindex` is inclusive, while `endindex` is exclusive. This function returns
an error if either index is outside the bounds of valid indices for the given
list.
## Examples
```shell-session
> slice(["a", "b", "c", "d"], 1, 3)
[
"b",
"c",
]
```
## Related Functions
- [`substr`](/docs/job-specification/hcl2/functions/string/substr) performs a similar function for characters in a
string, although it uses a length instead of an end index.

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: sort - Functions - Configuration Language
sidebar_title: sort
description: |-
The sort function takes a list of strings and returns a new list with those
strings sorted lexicographically.
---
# `sort` Function
`sort` takes a list of strings and returns a new list with those strings
sorted lexicographically.
The sort is in terms of Unicode codepoints, with higher codepoints appearing
after lower ones in the result.
## Examples
```shell-session
> sort(["e", "d", "a", "x"])
[
"a",
"d",
"e",
"x",
]
```

View File

@@ -0,0 +1,30 @@
---
layout: docs
page_title: values - Functions - Configuration Language
sidebar_title: values
description: The values function returns a list of the element values in a given map.
---
# `values` Function
`values` takes a map and returns a list containing the values of the elements
in that map.
The values are returned in lexicographical order by their corresponding _keys_,
so the values will be returned in the same order as their keys would be
returned from [`keys`](/docs/job-specification/hcl2/functions/collection/keys).
## Examples
```shell-session
> values({a=3, c=2, d=1})
[
3,
2,
1,
]
```
## Related Functions
- [`keys`](/docs/job-specification/hcl2/functions/collection/keys) returns a list of the _keys_ from a map.

View File

@@ -0,0 +1,35 @@
---
layout: docs
page_title: zipmap - Functions - Configuration Language
sidebar_title: zipmap
description: |-
The zipmap function constructs a map from a list of keys and a corresponding
list of values.
---
# `zipmap` Function
`zipmap` constructs a map from a list of keys and a corresponding list of
values.
```hcl
zipmap(keyslist, valueslist)
```
Both `keyslist` and `valueslist` must be of the same length. `keyslist` must
be a list of strings, while `valueslist` can be a list of any type.
Each pair of elements with the same index from the two lists will be used
as the key and value of an element in the resulting map. If the same value
appears multiple times in `keyslist` then the value with the highest index
is used in the resulting map.
## Examples
```shell-session
> zipmap(["a", "b"], [1, 2])
{
"a" = 1,
"b" = 2,
}
```

View File

@@ -0,0 +1,59 @@
---
layout: docs
page_title: can - Functions - Configuration Language
sidebar_title: can
description: |-
The can function tries to evaluate an expression given as an argument and
indicates whether the evaluation succeeded.
---
# `can` Function
`can` evaluates the given expression and returns a boolean value indicating
whether the expression produced a result without any errors.
This is a special function that is able to catch errors produced when evaluating
its argument. For most situations where you could use `can` it's better to use
[`try`](/docs/job-specification/hcl2/functions/conversion/try) instead, because it allows for more concise definition of
fallback values for failing expressions.
The `can` function can only catch and handle _dynamic_ errors resulting from
access to data that isn't known until runtime. It will not catch errors
relating to expressions that can be proven to be invalid for any input, such
as a malformed reference.
~> **Warning:** The `can` function is intended only for simple tests in
variable validation rules. Although it can technically accept any sort of
expression and be used elsewhere in the configuration, we recommend against
using it in other contexts. For error handling elsewhere in the configuration,
prefer to use [`try`](/docs/job-specification/hcl2/functions/conversion/try).
## Examples
```shell-session
> local.foo
{
"bar" = "baz"
}
> can(local.foo.bar)
true
> can(local.foo.boop)
false
```
The `can` function will _not_ catch errors relating to constructs that are
provably invalid even before dynamic expression evaluation, such as a malformed
reference or a reference to a top-level object that has not been declared:
```shell-session
> can(local.nonexist)
Error: Reference to undeclared local value
A local value with the name "nonexist" has not been declared.
```
## Related Functions
- [`try`](/docs/job-specification/hcl2/functions/conversion/try), which tries evaluating a sequence of expressions and
returns the result of the first one that succeeds.

View File

@@ -0,0 +1,54 @@
---
layout: docs
page_title: convert - Functions - Configuration Language
sidebar_title: convert
description: 'The convert function converts a value or an expression to a given type. '
---
# `convert` Function
`convert` converts a value or an expression to a given type.
Explicit type conversions are rarely necessary in HCL because it will convert
types automatically where required. Use the explicit type conversion functions
only to normalize types returned in outputs.
Only numbers and strings containing decimal representations of numbers can be
converted to number. All other values will produce an error.
Only boolean values and the exact strings "true" and "false" can be converted
to boolean. All other values will produce an error.
Only the primitive types (string, number, and bool) can be converted to string.
All other values will produce an error.
`convert(value, type_constraint)`
## Examples
```shell-session
> convert(3, string)
"3"
> convert("3", number)
3
> convert("false", bool)
false
> convert(false, string)
"false"
> convert(["a", "b", 3], list)
[
"a",
"b",
"3",
]
> convert(["c", "b", "b"], set)
[
"b",
"c",
]
> convert({"a" = "foo", "b" = true}, map)
{
"a" = "foo"
"b" = "true"
}
```

View File

@@ -0,0 +1,113 @@
---
layout: docs
page_title: try - Functions - Configuration Language
sidebar_title: try
description: |-
The try function tries to evaluate a sequence of expressions given as
arguments and returns the result of the first one that does not produce
any errors.
---
# `try` Function
`try` evaluates all of its argument expressions in turn and returns the result
of the first one that does not produce any errors.
This is a special function that is able to catch errors produced when evaluating
its arguments, which is particularly useful when working with complex data
structures whose shape is not well-known at implementation time.
For example, if some data is retrieved from an external system in JSON or YAML
format and then decoded, the result may have attributes that are not guaranteed
to be set. We can use `try` to produce a normalized data structure which has
a predictable type that can therefore be used more conveniently elsewhere in
the configuration:
```hcl
locals {
raw_value = yamldecode("${path.folder}/example.yaml")
normalized_value = {
name = tostring(try(local.raw_value.name, null))
groups = try(local.raw_value.groups, [])
}
}
```
With the above local value expressions, configuration elsewhere in the folder
can refer to `local.normalized_value` attributes without the need to repeatedly
check for and handle absent attributes that would otherwise produce errors.
We can also use `try` to deal with situations where a value might be provided
in two different forms, allowing us to normalize to the most general form:
```hcl
variable "example" {
type = any
}
locals {
example = try(
[tostring(var.example)],
tolist(var.example),
)
}
```
The above permits `var.example` to be either a list or a single string. If it's
a single string then it'll be normalized to a single-element list containing
that string, again allowing expressions elsewhere in the configuration to just
assume that `local.example` is always a list.
This second example contains two expressions that can both potentially fail.
For example, if `var.example` were set to `{}` then it could be converted to
neither a string nor a list. If `try` exhausts all of the given expressions
without any succeeding, it will return an error describing all of the problems
it encountered.
We strongly suggest using `try` only in special local values whose expressions
perform normalization, so that the error handling is confined to a single
location in the folder and the rest of the folder can just use straightforward
references to the normalized structure and thus be more readable for future
maintainers.
The `try` function can only catch and handle _dynamic_ errors resulting from
access to data that isn't known until runtime. It will not catch errors
relating to expressions that can be proven to be invalid for any input, such
as a malformed reference.
~> **Warning:** The `try` function is intended only for concise testing of the
presence of and types of object attributes. Although it can technically accept
any sort of expression, we recommend using it only with simple attribute
references and type conversion functions as shown in the examples above.
Overuse of `try` to suppress errors will lead to a configuration that is hard
to understand and maintain.
## Examples
```shell-session
> local.foo
{
"bar" = "baz"
}
> try(local.foo.bar, "fallback")
baz
> try(local.foo.boop, "fallback")
fallback
```
The `try` function will _not_ catch errors relating to constructs that are
provably invalid even before dynamic expression evaluation, such as a malformed
reference or a reference to a top-level object that has not been declared:
```shell-session
> try(local.nonexist, "fallback")
Error: Reference to undeclared local value
A local value with the name "nonexist" has not been declared.
```
## Related Functions
- [`can`](/docs/job-specification/hcl2/functions/conversion/can), which tries evaluating an expression and returns a
boolean value indicating whether it succeeded.

View File

@@ -0,0 +1,36 @@
---
layout: docs
page_title: bcrypt - Functions - Configuration Language
sidebar_title: bcrypt
description: |-
The bcrypt function computes a hash of the given string using the Blowfish
cipher.
---
# `bcrypt` Function
`bcrypt` computes a hash of the given string using the Blowfish cipher,
returning a string in [the _Modular Crypt
Format_](https://passlib.readthedocs.io/en/stable/modular_crypt_format.html)
usually expected in the shadow password file on many Unix systems.
```hcl
bcrypt(string, cost)
```
The `cost` argument is optional and will default to 10 if unspecified.
Since a bcrypt hash value includes a randomly selected salt, each call to this
function will return a different value, even if the given string and cost are
the same. Using this function directly with job arguments will therefore
cause spurious job updates.
The version prefix on the generated string (e.g. `$2a$`) may change in future
versions of Nomad.
## Examples
```shell-session
> bcrypt("hello world")
$2a$10$D5grTTzcsqyvAeIAnY/mYOIqliCoG7eAMX0/oFcuD.iErkksEbcAa
```

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: md5 - Functions - Configuration Language
sidebar_title: md5
description: |-
The md5 function computes the MD5 hash of a given string and encodes it
with hexadecimal digits.
---
# `md5` Function
`md5` computes the MD5 hash of a given string and encodes it with
hexadecimal digits.
The given string is first encoded as UTF-8 and then the MD5 algorithm is applied
as defined in [RFC 1321](https://tools.ietf.org/html/rfc1321). The raw hash is
then encoded to lowercase hexadecimal digits before returning.
Before using this function for anything security-sensitive, refer to
[RFC 6151](https://tools.ietf.org/html/rfc6151) for updated security
considerations applying to the MD5 algorithm.
## Examples
```shell-session
> md5("hello world")
5eb63bbbe01eeed093cb22bb8f5acdc3
```

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: rsadecrypt - Functions - Configuration Language
sidebar_title: rsadecrypt
description: The rsadecrypt function decrypts an RSA-encrypted message.
---
# `rsadecrypt` Function
`rsadecrypt` decrypts an RSA-encrypted ciphertext, returning the corresponding
cleartext.
```hcl
rsadecrypt(ciphertext, privatekey)
```
`ciphertext` must be a base64-encoded representation of the ciphertext, using
the PKCS #1 v1.5 padding scheme. Nomad uses the "standard" Base64 alphabet
as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
`privatekey` must be a PEM-encoded RSA private key that is not itself
encrypted.
Nomad has no corresponding function for _encrypting_ a message. Use this
function to decrypt ciphertexts returned by remote services using a keypair
negotiated out-of-band.
## Examples
```shell-session
> rsadecrypt(base64(file("${path.folder}/ciphertext")), file("privatekey.pem"))
Hello, world!
```

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: sha1 - Functions - Configuration Language
sidebar_title: sha1
description: |-
The sha1 function computes the SHA1 hash of a given string and encodes it
with hexadecimal digits.
---
# `sha1` Function
`sha1` computes the SHA1 hash of a given string and encodes it with
hexadecimal digits.
The given string is first encoded as UTF-8 and then the SHA1 algorithm is applied
as defined in [RFC 3174](https://tools.ietf.org/html/rfc3174). The raw hash is
then encoded to lowercase hexadecimal digits before returning.
Collision attacks have been successfully performed against this hashing
function. Before using this function for anything security-sensitive, review
relevant literature to understand the security implications.
## Examples
```shell-session
> sha1("hello world")
2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
```

View File

@@ -0,0 +1,24 @@
---
layout: docs
page_title: sha256 - Functions - Configuration Language
sidebar_title: sha256
description: |-
The sha256 function computes the SHA256 hash of a given string and encodes it
with hexadecimal digits.
---
# `sha256` Function
`sha256` computes the SHA256 hash of a given string and encodes it with
hexadecimal digits.
The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
then encoded to lowercase hexadecimal digits before returning.
## Examples
```shell-session
> sha256("hello world")
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
```

View File

@@ -0,0 +1,24 @@
---
layout: docs
page_title: sha512 - Functions - Configuration Language
sidebar_title: sha512
description: |-
The sha512 function computes the SHA512 hash of a given string and encodes it
with hexadecimal digits.
---
# `sha512` Function
`sha512` computes the SHA512 hash of a given string and encodes it with
hexadecimal digits.
The given string is first encoded as UTF-8 and then the SHA512 algorithm is applied
as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
then encoded to lowercase hexadecimal digits before returning.
## Examples
```shell-session
> sha512("hello world")
309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
```

View File

@@ -0,0 +1,107 @@
---
layout: docs
page_title: formatdate - Functions - Configuration Language
sidebar_title: formatdate
description: The formatdate function converts a timestamp into a different time format.
---
# `formatdate` Function
`formatdate` converts a timestamp into a different time format.
```hcl
formatdate(spec, timestamp)
```
In Nomad, timestamps are conventionally represented as strings using [RFC
3339](https://tools.ietf.org/html/rfc3339) "Date and Time format" syntax.
`formatdate` requires the `timestamp` argument to be a string conforming to
this syntax.
## Examples
```shell-session
> formatdate("DD MMM YYYY hh:mm ZZZ", "2018-01-02T23:12:01Z")
02 Jan 2018 23:12 UTC
> formatdate("EEEE, DD-MMM-YY hh:mm:ss ZZZ", "2018-01-02T23:12:01Z")
Tuesday, 02-Jan-18 23:12:01 UTC
> formatdate("EEE, DD MMM YYYY hh:mm:ss ZZZ", "2018-01-02T23:12:01-08:00")
Tue, 02 Jan 2018 23:12:01 -0800
> formatdate("MMM DD, YYYY", "2018-01-02T23:12:01Z")
Jan 02, 2018
> formatdate("HH:mmaa", "2018-01-02T23:12:01Z")
11:12pm
```
## Specification Syntax
The format specification is a string that includes formatting sequences from
the following table. This function is intended for producing common
_machine-oriented_ timestamp formats such as those defined in RFC822, RFC850,
and RFC1123. It is not suitable for truly human-oriented date formatting
because it is not locale-aware. In particular, it can produce month and day
names only in English.
The specification may contain the following sequences:
| Sequence | Result |
| -------- | ----------------------------------------------------------------------- |
| `YYYY` | Four (or more) digit year, like "2006". |
| `YY` | The year modulo 100, zero padded to at least two digits, like "06". |
| `MMMM` | English month name unabbreviated, like "January". |
| `MMM` | English month name abbreviated to three letters, like "Jan". |
| `MM` | Month number zero-padded to two digits, like "01" for January. |
| `M` | Month number with no padding, like "1" for January. |
| `DD` | Day of month number zero-padded to two digits, like "02". |
| `D` | Day of month number with no padding, like "2". |
| `EEEE` | English day of week name unabbreviated, like "Monday". |
| `EEE` | English day of week name abbreviated to three letters, like "Mon". |
| `hh` | 24-hour number zero-padded to two digits, like "02". |
| `h` | 24-hour number unpadded, like "2". |
| `HH` | 12-hour number zero-padded to two digits, like "02". |
| `H` | 12-hour number unpadded, like "2". |
| `AA` | Hour AM/PM marker in uppercase, like "AM". |
| `aa` | Hour AM/PM marker in lowercase, like "am". |
| `mm` | Minute within hour zero-padded to two digits, like "05". |
| `m` | Minute within hour unpadded, like "5". |
| `ss` | Second within minute zero-padded to two digits, like "09". |
| `s` | Second within minute, like "9". |
| `ZZZZZ` | Timezone offset with colon separating hours and minutes, like "-08:00". |
| `ZZZZ` | Timezone offset with just sign and digit, like "-0800". |
| `ZZZ` | Like `ZZZZ` but with a special case "UTC" for UTC. |
| `Z` | Like `ZZZZZ` but with a special case "Z" for UTC. |
Any non-letter characters, such as punctuation, are reproduced verbatim in the
output. To include literal letters in the format string, enclose them in single
quotes `'`. To include a literal quote, escape it by doubling the quotes.
```shell-session
> formatdate("h'h'mm", "2018-01-02T23:12:01-08:00")
23h12
> formatdate("H 'o''clock'", "2018-01-02T23:12:01-08:00")
11 o'clock
```
This format specification syntax is intended to make it easy for a reader
to guess which format will result even if they are not experts on the syntax.
Therefore there are no predefined shorthands for common formats, but format
strings for various RFC-specified formats are given below to be copied into your
configuration as needed:
- [RFC 822](https://tools.ietf.org/html/rfc822#section-5) and
[RFC RFC 2822](https://tools.ietf.org/html/rfc2822#section-3.3):
`"DD MMM YYYY hh:mm ZZZ"`
- [RFC 850](https://tools.ietf.org/html/rfc850#section-2.1.4):
`"EEEE, DD-MMM-YY hh:mm:ss ZZZ"`
- [RFC 1123](https://tools.ietf.org/html/rfc1123#section-5.2.14):
`"EEE, DD MMM YYYY hh:mm:ss ZZZ"`
- [RFC 3339](https://tools.ietf.org/html/rfc3339):
`"YYYY-MM-DD'T'hh:mm:ssZ"` (but this is also the input format, so such a
conversion is redundant.)
## Related Functions
- [`format`](/docs/job-specification/hcl2/functions/string/format) is a more general formatting function for arbitrary
data.
- [`timestamp`](/docs/job-specification/hcl2/functions/datetime/timestamp) returns the current date and time in a format
suitable for input to `formatdate`.

View File

@@ -0,0 +1,36 @@
---
layout: docs
page_title: timeadd - Functions - Configuration Language
sidebar_title: timeadd
description: |-
The timeadd function adds a duration to a timestamp, returning a new
timestamp.
---
# `timeadd` Function
`timeadd` adds a duration to a timestamp, returning a new timestamp.
```hcl
timeadd(timestamp, duration)
```
In the Nomad language, timestamps are conventionally represented as
strings using [RFC 3339](https://tools.ietf.org/html/rfc3339)
"Date and Time format" syntax. `timeadd` requires the `timestamp` argument
to be a string conforming to this syntax.
`duration` is a string representation of a time difference, consisting of
sequences of number and unit pairs, like `"1.5h"` or `"1h30m"`. The accepted
units are `"ns"`, `"us"` (or `"µs"`), `"ms"`, `"s"`, `"m"`, and `"h"`. The first
number may be negative to indicate a negative duration, like `"-2h5m"`.
The result is a string, also in RFC 3339 format, representing the result
of adding the given direction to the given timestamp.
## Examples
```shell-session
> timeadd("2017-11-22T00:00:00Z", "10m")
2017-11-22T00:10:00Z
```

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: timestamp - Functions - Configuration Language
sidebar_title: timestamp
description: |-
The timestamp function returns a string representation of the current date
and time.
---
# `timestamp` Function
`timestamp` returns the current date and time.
In the Nomad language, timestamps are conventionally represented as
strings using [RFC 3339](https://tools.ietf.org/html/rfc3339)
"Date and Time format" syntax, and so `timestamp` returns a string
in this format.
The result of this function will change every second, so using this function
directly with job attributes will cause a diff to be detected on every
Nomad job submission.
## Examples
```shell-session
> timestamp()
2018-05-13T07:44:12Z
```
## Related Functions
- [`formatdate`](/docs/job-specification/hcl2/functions/datetime/formatdate) can convert the resulting timestamp to
other date and time formats.

View File

@@ -0,0 +1,31 @@
---
layout: docs
page_title: base64decode - Functions - Configuration Language
sidebar_title: base64decode
description: The base64decode function decodes a string containing a base64 sequence.
---
# `base64decode` Function
`base64decode` takes a string containing a Base64 character sequence and
returns the original string.
Nomad uses the "standard" Base64 alphabet as defined in
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
Strings in the Nomad language are sequences of unicode characters rather
than bytes, so this function will also interpret the resulting bytes as
UTF-8. If the bytes after Base64 decoding are _not_ valid UTF-8, this function
produces an error.
## Examples
```shell-session
> base64decode("SGVsbG8gV29ybGQ=")
Hello World
```
## Related Functions
- [`base64encode`](/docs/job-specification/hcl2/functions/encoding/base64encode) performs the opposite operation,
encoding the UTF-8 bytes for a string as Base64.

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: base64encode - Functions - Configuration Language
sidebar_title: base64encode
description: The base64encode function applies Base64 encoding to a string.
---
# `base64encode` Function
`base64encode` applies Base64 encoding to a string.
Nomad uses the "standard" Base64 alphabet as defined in
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
Strings in the Nomad language are sequences of unicode characters rather
than bytes, so this function will first encode the characters from the string
as UTF-8, and then apply Base64 encoding to the result.
The Nomad language applies Unicode normalization to all strings, and so
passing a string through `base64decode` and then `base64encode` may not yield
the original result exactly.
## Examples
```shell-session
> base64encode("Hello World")
SGVsbG8gV29ybGQ=
```
## Related Functions
- [`base64decode`](/docs/job-specification/hcl2/functions/encoding/base64decode) performs the opposite operation,
decoding Base64 data and interpreting it as a UTF-8 string.

View File

@@ -0,0 +1,101 @@
---
layout: docs
page_title: csvdecode - Functions - Configuration Language
sidebar_title: csvdecode
description: The csvdecode function decodes CSV data into a list of maps.
---
# `csvdecode` Function
`csvdecode` decodes a string containing CSV-formatted data and produces a
list of maps representing that data.
CSV is _Comma-separated Values_, an encoding format for tabular data. There
are many variants of CSV, but this function implements the format defined
in [RFC 4180](https://tools.ietf.org/html/rfc4180).
The first line of the CSV data is interpreted as a "header" row: the values
given are used as the keys in the resulting maps. Each subsequent line becomes
a single map in the resulting list, matching the keys from the header row
with the given values by index. All lines in the file must contain the same
number of fields, or this function will produce an error.
## Examples
```shell-session
> csvdecode("a,b,c\n1,2,3\n4,5,6")
[
{
"a" = "1"
"b" = "2"
"c" = "3"
},
{
"a" = "4"
"b" = "5"
"c" = "6"
}
]
```
<!---
## TODO: revamp this section
## Use with the `for_each` meta-argument
You can use the result of `csvdecode` with
[the `for_each` meta-argument](https://www.terraform.io/docs/configuration/resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings)
to describe a collection of similar objects whose differences are
described by the rows in the given CSV file.
There must be one column in the CSV file that can serve as a unique id for each
row, which we can then use as the tracking key for the individual instances in
the `for_each` expression. For example:
```hcl
locals {
# We've included this inline to create a complete example, but in practice
# this is more likely to be loaded from a file using the "file" function.
csv_data = <<-CSV
local_id,instance_type,ami
foo1,t2.micro,ami-54d2a63b
foo2,t2.micro,ami-54d2a63b
foo3,t2.micro,ami-54d2a63b
bar1,m3.large,ami-54d2a63b
CSV
instances = csvdecode(local.csv_data)
}
resource "aws_instance" "example" {
for_each = { for inst in local.instances : inst.local_id => inst }
instance_type = each.value.instance_type
ami = each.value.ami
}
```
The `for` expression in our `for_each` argument transforms the list produced
by `csvdecode` into a map using the `local_id` as a key, which tells
Packer to use the `local_id` value to track each instance it creates.
Packer will create and manage the following instance addresses:
- `aws_instance.example["foo1"]`
- `aws_instance.example["foo2"]`
- `aws_instance.example["foo3"]`
- `aws_instance.example["bar1"]`
If you modify a row in the CSV on a subsequent plan, Packer will interpret
that as an update to the existing object as long as the `local_id` value is
unchanged. If you add or remove rows from the CSV then Packer will plan to
create or destroy associated instances as appropriate.
If there is no reasonable value you can use as a unique identifier in your CSV
then you could instead use
[the `count` meta-argument](https://www.terraform.io/docs/configuration/resources.html#count-multiple-resource-instances-by-count)
to define an object for each CSV row, with each one identified by its index into
the list returned by `csvdecode`. However, in that case any future updates to
the CSV may be disruptive if they change the positions of particular objects in
the list. We recommend using `for_each` with a unique id column to make
behavior more predictable on future changes.
-->

View File

@@ -0,0 +1,48 @@
---
layout: docs
page_title: jsondecode - Functions - Configuration Language
sidebar_title: jsondecode
description: |-
The jsondecode function decodes a JSON string into a representation of its
value.
---
# `jsondecode` Function
`jsondecode` interprets a given string as JSON, returning a representation
of the result of decoding that string.
The JSON encoding is defined in [RFC 7159](https://tools.ietf.org/html/rfc7159).
This function maps JSON values to
[Nomad language values](/docs/job-specification/hcl2/expressions#types-and-values)
in the following way:
| JSON type | Nomad type |
| --------- | ------------------------------------------------------------ |
| String | `string` |
| Number | `number` |
| Boolean | `bool` |
| Object | `object(...)` with attribute types determined per this table |
| Array | `tuple(...)` with element types determined per this table |
| Null | The Nomad language `null` value |
The Nomad language automatic type conversion rules mean that you don't
usually need to worry about exactly what type is produced for a given value,
and can just use the result in an intuitive way.
## Examples
```shell-session
> jsondecode("{\"hello\": \"world\"}")
{
"hello" = "world"
}
> jsondecode("true")
true
```
## Related Functions
- [`jsonencode`](/docs/job-specification/hcl2/functions/encoding/jsonencode) performs the opposite operation, _encoding_
a value as JSON.

View File

@@ -0,0 +1,45 @@
---
layout: docs
page_title: jsonencode - Functions - Configuration Language
sidebar_title: jsonencode
description: The jsonencode function encodes a given value as a JSON string.
---
# `jsonencode` Function
`jsonencode` encodes a given value to a string using JSON syntax.
The JSON encoding is defined in [RFC 7159](https://tools.ietf.org/html/rfc7159).
This function maps
[Nomad language values](/docs/job-specification/hcl2/expressions#types-and-values)
to JSON values in the following way:
| Nomad type | JSON type |
| ------------- | --------- |
| `string` | String |
| `number` | Number |
| `bool` | Bool |
| `list(...)` | Array |
| `set(...)` | Array |
| `tuple(...)` | Array |
| `map(...)` | Object |
| `object(...)` | Object |
| Null value | `null` |
Since the JSON format cannot fully represent all of the Nomad language
types, passing the `jsonencode` result to `jsondecode` will not produce an
identical value, but the automatic type conversion rules mean that this is
rarely a problem in practice.
## Examples
```shell-session
> jsonencode({"hello"="world"})
{"hello":"world"}
```
## Related Functions
- [`jsondecode`](/docs/job-specification/hcl2/functions/encoding/jsondecode) performs the opposite operation, _decoding_
a JSON string to obtain its represented value.

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: urlencode - Functions - Configuration Language
sidebar_title: urlencode
description: The urlencode function applies URL encoding to a given string.
---
# `urlencode` Function
`urlencode` applies URL encoding to a given string.
This function identifies characters in the given string that would have a
special meaning when included as a query string argument in a URL and
escapes them using
[RFC 3986 "percent encoding"](https://tools.ietf.org/html/rfc3986#section-2.1).
The exact set of characters escaped may change over time, but the result
is guaranteed to be interpolatable into a query string argument without
inadvertently introducing additional delimiters.
If the given string contains non-ASCII characters, these are first encoded as
UTF-8 and then percent encoding is applied separately to each UTF-8 byte.
## Examples
```shell-session
> urlencode("Hello World")
Hello%20World
> urlencode("☃")
%E2%98%83
> "http://example.com/search?q=${urlencode("nomad urlencode")}"
http://example.com/search?q=nomad%20urlencode
```

View File

@@ -0,0 +1,101 @@
---
layout: docs
page_title: yamldecode - Functions - Configuration Language
sidebar_title: yamldecode
description: |-
The yamldecode function decodes a YAML string into a representation of its
value.
---
# `yamldecode` Function
`yamldecode` parses a string as a subset of YAML, and produces a representation
of its value.
This function supports a subset of [YAML 1.2](https://yaml.org/spec/1.2/spec.html),
as described below.
This function maps YAML values to
[Nomad language values](/docs/job-specification/hcl2/expressions#types-and-values)
in the following way:
| YAML type | Nomad type |
| ------------- | ------------------------------------------------------------------ |
| `!!str` | `string` |
| `!!float` | `number` |
| `!!int` | `number` |
| `!!bool` | `bool` |
| `!!map` | `object(...)` with attribute types determined per this table |
| `!!seq` | `tuple(...)` with element types determined per this table |
| `!!null` | The Nomad language `null` value |
| `!!timestamp` | `string` in [RFC 3339](https://tools.ietf.org/html/rfc3339) format |
| `!!binary` | `string` containing base64-encoded representation |
The Nomad language automatic type conversion rules mean that you don't
usually need to worry about exactly what type is produced for a given value,
and can just use the result in an intuitive way.
Note though that the mapping above is ambiguous -- several different source
types map to the same target type -- and so round-tripping through `yamldecode`
and then `yamlencode` cannot produce an identical result.
YAML is a complex language and it supports a number of possibilities that the
Nomad language's type system cannot represent. Therefore this YAML decoder
supports only a subset of YAML 1.2, with restrictions including the following:
- Although aliases to earlier anchors are supported, cyclic data structures
(where a reference to a collection appears inside that collection) are not.
If `yamldecode` detects such a structure then it will return an error.
- Only the type tags shown in the above table (or equivalent alternative
representations of those same tags) are supported. Any other tags will
result in an error.
- Only one YAML document is permitted. If multiple documents are present in
the given string then this function will return an error.
## Examples
```shell-session
> yamldecode("{\"hello\": \"world\"}")
{
"hello" = "world"
}
> yamldecode("true")
true
> yamldecode("{a: &foo [1, 2, 3], b: *foo}")
{
"a" = [
1,
2,
3,
]
"b" = [
1,
2,
3,
]
}
> yamldecode("{a: &foo [1, *foo, 3]}")
Error: Error in function call
Call to function "yamldecode" failed: cannot refer to anchor "foo" from inside
its own definition.
> yamldecode("{a: !not-supported foo}")
Error: Error in function call
Call to function "yamldecode" failed: unsupported tag "!not-supported".
```
## Related Functions
- [`jsondecode`](/docs/job-specification/hcl2/functions/encoding/jsondecode) is a similar operation using JSON instead
of YAML.
- [`yamlencode`](/docs/job-specification/hcl2/functions/encoding/yamlencode) performs the opposite operation, _encoding_
a value as YAML.

View File

@@ -0,0 +1,87 @@
---
layout: docs
page_title: yamlencode - Functions - Configuration Language
sidebar_title: yamlencode
description: The yamlencode function encodes a given value as a YAML string.
---
# `yamlencode` Function
`yamlencode` encodes a given value to a string using
[YAML 1.2](https://yaml.org/spec/1.2/spec) block syntax.
~> **Warning:** This function is currently **experimental** and its exact
result format may change in future versions of Nomad, based on feedback.
Do not use `yamldecode` to construct a value for any argument where
changes to the result would be disruptive. To get a consistent string
representation of a value use [`jsonencode`](/docs/job-specification/hcl2/functions/encoding/jsonencode) instead; its
results are also valid YAML because YAML is a JSON superset.
<!--
The condition for removing the above warning is that the underlying
go-cty-yaml folder makes a stable release with a commitment to guarantee
that the representation of particular input will not change without a
major release. It is not making that commitment at the time of writing to
allow for responding to user feedback about its output format, since YAML
is a very flexible format and its initial decisions may prove to be
sub-optimal when generating YAML intended for specific external consumers.
-->
This function maps
[Nomad language values](/docs/job-specification/hcl2/expressions#types-and-values)
to YAML tags in the following way:
| Nomad type | YAML type |
| ------------- | -------------------- |
| `string` | `!!str` |
| `number` | `!!float` or `!!int` |
| `bool` | `!!bool` |
| `list(...)` | `!!seq` |
| `set(...)` | `!!seq` |
| `tuple(...)` | `!!seq` |
| `map(...)` | `!!map` |
| `object(...)` | `!!map` |
| Null value | `!!null` |
`yamlencode` uses the implied syntaxes for all of the above types, so it does
not generate explicit YAML tags.
Because the YAML format cannot fully represent all of the Nomad language
types, passing the `yamlencode` result to `yamldecode` will not produce an
identical value, but the Nomad language automatic type conversion rules
mean that this is rarely a problem in practice.
## Examples
```shell-session
> yamlencode({"a":"b", "c":"d"})
"a": "b"
"c": "d"
> yamlencode({"foo":[1, 2, 3], "bar": "baz"})
"bar": "baz"
"foo":
- 1
- 2
- 3
> yamlencode({"foo":[1, {"a":"b","c":"d"}, 3], "bar": "baz"})
"bar": "baz"
"foo":
- 1
- "a": "b"
"c": "d"
- 3
```
`yamlencode` always uses YAML's "block style" for mappings and sequences, unless
the mapping or sequence is empty. To generate flow-style YAML, use
[`jsonencode`](/docs/job-specification/hcl2/functions/encoding/jsonencode) instead: YAML flow-style is a superset
of JSON syntax.
## Related Functions
- [`jsonencode`](/docs/job-specification/hcl2/functions/encoding/jsonencode) is a similar operation using JSON instead
of YAML.
- [`yamldecode`](/docs/job-specification/hcl2/functions/encoding/yamldecode) performs the opposite operation, _decoding_
a YAML string to obtain its represented value.

View File

@@ -0,0 +1,26 @@
---
layout: docs
page_title: abspath - Functions - Configuration Language
sidebar_title: abspath
description: The abspath function converts the argument to an absolute filesystem path.
---
# `abspath` Function
`abspath` takes a string containing a filesystem path and converts it
to an absolute path. That is, if the path is not absolute, it will be joined
with the job file directory.
Referring directly to filesystem paths in job arguments may cause spurious
diffs if the same configuration is applied from multiple systems or on
different host operating systems. We recommend using filesystem paths only for
transient values, such as the argument to
[`file`](/docs/job-specification/hcl2/functions/file/file) (where only the contents are then
stored).
## Examples
```shell-session
> abspath("nomad.txt")
/home/user/some/nomad-job/nomad.txt
```

View File

@@ -0,0 +1,42 @@
---
layout: docs
page_title: basename - Functions - Configuration Language
sidebar_title: basename
description: |-
The basename function removes all except the last portion from a filesystem
path.
---
# `basename` Function
`basename` takes a string containing a filesystem path and removes all except
the last portion from it.
This function works only with the path string and does not access the
filesystem itself. It is therefore unable to take into account filesystem
features such as symlinks.
If the path is empty then the result is `"."`, representing the job file directory.
The behavior of this function depends on the host platform. On Windows systems,
it uses backslash `\` as the path segment separator. On Unix systems, the slash
`/` is used.
Referring directly to filesystem paths in job arguments may cause
spurious diffs if the same configuration is applied from multiple systems or on
different host operating systems. We recommend using filesystem paths only
for transient values, such as the argument to [`file`](/docs/job-specification/hcl2/functions/file/file) (where
only the contents are then stored).
## Examples
```shell-session
> basename("foo/bar/baz.txt")
baz.txt
```
## Related Functions
- [`dirname`](/docs/job-specification/hcl2/functions/file/dirname) returns all of the segments of a filesystem path
_except_ the last, discarding the portion that would be returned by
`basename`.

View File

@@ -0,0 +1,40 @@
---
layout: docs
page_title: dirname - Functions - Configuration Language
sidebar_title: dirname
description: The dirname function removes the last portion from a filesystem path.
---
# `dirname` Function
`dirname` takes a string containing a filesystem path and removes the last
portion from it.
This function works only with the path string and does not access the
filesystem itself. It is therefore unable to take into account filesystem
features such as symlinks.
If the path is empty then the result is `"."`, representing the job file directory.
The behavior of this function depends on the host platform. On Windows systems,
it uses backslash `\` as the path segment separator. On Unix systems, the slash
`/` is used. The result of this function is normalized, so on a Windows system
any slashes in the given path will be replaced by backslashes before returning.
Referring directly to filesystem paths in job arguments may cause
spurious diffs if the same configuration is applied from multiple systems or on
different host operating systems. We recommend using filesystem paths only
for transient values, such as the argument to [`file`](/docs/job-specification/hcl2/functions/file/file) (where
only the contents are then stored).
## Examples
```shell-session
> dirname("foo/bar/baz.txt")
foo/bar
```
## Related Functions
- [`basename`](/docs/job-specification/hcl2/functions/file/basename) returns _only_ the last portion of a filesystem
path, discarding the portion that would be returned by `dirname`.

View File

@@ -0,0 +1,37 @@
---
layout: docs
page_title: file - Functions - Configuration Language
sidebar_title: file
description: |-
The file function reads the contents of the file at the given path and
returns them as a string.
---
# `file` Function
`file` reads the contents of a file at the given path and returns them as
a string.
```hcl
file(path)
```
Strings in the Nomad language are sequences of Unicode characters, so
this function will interpret the file contents as UTF-8 encoded text and
return the resulting Unicode characters. If the file contains invalid UTF-8
sequences then this function will produce an error.
Functions are evaluated by the CLI during configuration parsing rather than job run time,
so this function can only be used with files that are already present on disk on operator host.
## Examples
```shell-session
> file("./hello.txt")
Hello World
```
## Related Functions
- [`fileexists`](/docs/job-specification/hcl2/functions/file/fileexists) determines whether a file exists
at a given path.

View File

@@ -0,0 +1,35 @@
---
layout: docs
page_title: fileexists - Functions - Configuration Language
sidebar_title: fileexists
description: The fileexists function determines whether a file exists at a given path.
---
# `fileexists` Function
`fileexists` determines whether a file exists at a given path.
```hcl
fileexists(path)
```
Functions are evaluated by the CLI during configuration parsing rather than job run time,
so this function can only be used with files that are already present on disk on operator host.
This function works only with regular files. If used with a directory, FIFO,
or other special mode, it will return an error.
## Examples
```shell-session
> fileexists("./hello.txt")
true
```
```hcl
fileexists("custom-section.sh") ? file("custom-section.sh") : local.default_content
```
## Related Functions
- [`file`](/docs/job-specification/hcl2/functions/file/file) reads the contents of a file at a given path

View File

@@ -0,0 +1,82 @@
---
layout: docs
page_title: fileset - Functions - Configuration Language
sidebar_title: fileset
description: The fileset function enumerates a set of regular file names given a pattern.
---
# `fileset` Function
`fileset` enumerates a set of regular file names given a path and pattern.
The path is automatically removed from the resulting set of file names and any
result still containing path separators always returns forward slash (`/`) as
the path separator for cross-system compatibility.
```hcl
fileset(path, pattern)
```
Supported pattern matches:
- `*` - matches any sequence of non-separator characters
- `**` - matches any sequence of characters, including separator characters
- `?` - matches any single non-separator character
- `{alternative1,...}` - matches a sequence of characters if one of the comma-separated alternatives matches
- `[CLASS]` - matches any single non-separator character inside a class of characters (see below)
- `[^CLASS]` - matches any single non-separator character outside a class of characters (see below)
Character classes support the following:
- `[abc]` - matches any single character within the set
- `[a-z]` - matches any single character within the range
Functions are evaluated by the CLI during configuration parsing rather than job run time,
so this function can only be used with files that are already present on disk on operator host.
## Examples
```shell-session
> tree pkr-consul
pkr-consul
├── build-linux.pkr.hcl
└── linux
├── files
│ ├── hello.txt
│ └── world.txt
└── scripts
├── script-1-install.sh
└── script-2-setup.sh
3 directories, 5 files
> fileset(".", "*")
[
"build-linux.pkr.hcl",
]
> echo 'fileset(".", "linux/scripts/*")'
[
"linux/scripts/script-1-install.sh",
"linux/scripts/script-2-setup.sh",
]
> echo 'fileset("linux", "files/{hello,world}.txt")'
[
"files/hello.txt",
"files/world.txt",
]
> echo 'fileset("./linux/files", "*")'
[
"hello.txt",
"world.txt",
]
> echo 'fileset("./linux", "**")'
[
"files/hello.txt",
"files/world.txt",
"scripts/script-1-install.sh",
"scripts/script-2-setup.sh",
]
```

View File

@@ -0,0 +1,54 @@
---
layout: docs
page_title: pathexpand - Functions - Configuration Language
sidebar_title: pathexpand
description: |-
The pathexpand function expands a leading ~ character to the current user's
home directory.
---
# `pathexpand` Function
`pathexpand` takes a filesystem path that might begin with a `~` segment,
and if so it replaces that segment with the current user's home directory
path.
This function works only with the path string and does not access the
filesystem itself. It is therefore unable to take into account filesystem
features such as symlinks.
If the leading segment in the path is not `~` then the given path is returned
unmodified.
Using this function in job arguments will cause spurious diffs if the
same configuration is run by multiple users with different home directory
paths, or used on different host operating systems.
The rules for determining the "home directory" for the current user vary
depending on host operating system.
**For Unix systems**, the following sources are consulted, in order of preference:
- The `HOME` environment variable.
- The result of running `getent passwd` followed by the Nomad process uid.
- The result of running `cd && pwd` in `sh`.
**For Windows systems**, there is not really the concept of a home directory
in the same sense as on Unix, but the following sources are consulted in
order of preference:
- The `HOME` environment variable.
- The `HOMEDRIVE` and `HOMEPATH` environment variables, if both are set.
- The `USERPROFILE` environment variable.
The exact rules employed for each operating system may change in future
releases of Nomad.
## Examples
```shell-session
> pathexpand("~/.ssh/id_rsa")
/home/steve/.ssh/id_rsa
> pathexpand("/etc/resolv.conf")
/etc/resolv.conf
```

View File

@@ -0,0 +1,25 @@
---
layout: docs
page_title: Functions - Configuration Language
sidebar_title: Functions
description: |-
The HCL language has a number of built-in functions that can be called
from within expressions to transform and combine values.
---
# Built-in Functions
`@include 'beta-nomad1.0-note.mdx'`
The HCL language includes a number of built-in functions that you can
call from within expressions to transform and combine values. The general
syntax for function calls is a function name followed by comma-separated
arguments in parentheses:
```hcl
max(5, 12, 9)
```
The HCL language does not support user-defined functions, and so only
the functions built in to the language are available for use. The navigation
for this section includes a list of all of the available built-in functions.

View File

@@ -0,0 +1,51 @@
---
layout: docs
page_title: cidrhost - Functions - Configuration Language
sidebar_title: cidrhost
description: |-
The cidrhost function calculates a full host IP address within a given
IP network address prefix.
---
# `cidrhost` Function
`cidrhost` calculates a full host IP address for a given host number within
a given IP network address prefix.
```hcl
cidrhost(prefix, hostnum)
```
`prefix` must be given in CIDR notation, as defined in
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
`hostnum` is a whole number that can be represented as a binary integer with
no more than the number of digits remaining in the address after the given
prefix. For more details on how this function interprets CIDR prefixes and
populates host numbers, see the worked example for
[`cidrsubnet`](/docs/job-specification/hcl2/functions/ipnet/cidrsubnet).
Conventionally host number zero is used to represent the address of the
network itself and the host number that would fill all the host bits with
binary 1 represents the network's broadcast address. These numbers should
generally not be used to identify individual hosts except in unusual
situations, such as point-to-point links.
This function accepts both IPv6 and IPv4 prefixes, and the result always uses
the same addressing scheme as the given prefix.
## Examples
```shell-session
> cidrhost("10.12.127.0/20", 16)
10.12.112.16
> cidrhost("10.12.127.0/20", 268)
10.12.113.12
> cidrhost("fd00:fd12:3456:7890:00a2::/72", 34)
fd00:fd12:3456:7890::22
```
## Related Functions
- [`cidrsubnet`](/docs/job-specification/hcl2/functions/ipnet/cidrsubnet) calculates a subnet address under a given
network address prefix.

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: cidrnetmask - Functions - Configuration Language
sidebar_title: cidrnetmask
description: |-
The cidrnetmask function converts an IPv4 address prefix given in CIDR
notation into a subnet mask address.
---
# `cidrnetmask` Function
`cidrnetmask` converts an IPv4 address prefix given in CIDR notation into
a subnet mask address.
```hcl
cidrnetmask(prefix)
```
`prefix` must be given in IPv4 CIDR notation, as defined in
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
The result is a subnet address formatted in the conventional dotted-decimal
IPv4 address syntax, as expected by some software.
CIDR notation is the only valid notation for IPv6 addresses, so `cidrnetmask`
produces an error if given an IPv6 address.
## Examples
```shell-session
> cidrnetmask("172.16.0.0/12")
255.240.0.0
```

View File

@@ -0,0 +1,168 @@
---
layout: docs
page_title: cidrsubnet - Functions - Configuration Language
sidebar_title: cidrsubnet
description: |-
The cidrsubnet function calculates a subnet address within a given IP network
address prefix.
---
# `cidrsubnet` Function
`cidrsubnet` calculates a subnet address within given IP network address prefix.
```hcl
cidrsubnet(prefix, newbits, netnum)
```
`prefix` must be given in CIDR notation, as defined in
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
`newbits` is the number of additional bits with which to extend the prefix.
For example, if given a prefix ending in `/16` and a `newbits` value of
`4`, the resulting subnet address will have length `/20`.
`netnum` is a whole number that can be represented as a binary integer with
no more than `newbits` binary digits, which will be used to populate the
additional bits added to the prefix.
This function accepts both IPv6 and IPv4 prefixes, and the result always uses
the same addressing scheme as the given prefix.
Unlike the related function [`cidrsubnets`](/docs/job-specification/hcl2/functions/ipnet/cidrsubnets), `cidrsubnet`
allows you to give a specific network number to use. `cidrsubnets` can allocate
multiple network addresses at once, but numbers them automatically starting
with zero.
## Examples
```shell-session
> cidrsubnet("172.16.0.0/12", 4, 2)
172.18.0.0/16
> cidrsubnet("10.1.2.0/24", 4, 15)
10.1.2.240/28
> cidrsubnet("fd00:fd12:3456:7890::/56", 16, 162)
fd00:fd12:3456:7800:a200::/72
```
## Netmasks and Subnets
Using `cidrsubnet` requires familiarity with some network addressing concepts.
The most important idea is that an IP address (whether IPv4 or IPv6) is
fundamentally constructed from binary digits, even though we conventionally
represent it as either four decimal octets (for IPv4) or a sequence of 16-bit
hexadecimal numbers (for IPv6).
Taking our example above of `cidrsubnet("10.1.2.0/24", 4, 15)`, the function
will first convert the given IP address string into an equivalent binary
representation:
```text
10 . 1 . 2 . 0
00001010 00000001 00000010 | 00000000
network | host
```
The `/24` at the end of the prefix string specifies that the first 24
bits -- or, the first three octets -- of the address identify the network
while the remaining bits (32 - 24 = 8 bits in this case) identify hosts
within the network.
The CLI tool [`ipcalc`](https://gitlab.com/ipcalc/ipcalc) is useful for
visualizing CIDR prefixes as binary numbers. We can confirm the conversion
above by providing the same prefix string to `ipcalc`:
```shell-session
$ ipcalc 10.1.2.0/24
Address: 10.1.2.0 00001010.00000001.00000010. 00000000
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111
=>
Network: 10.1.2.0/24 00001010.00000001.00000010. 00000000
HostMin: 10.1.2.1 00001010.00000001.00000010. 00000001
HostMax: 10.1.2.254 00001010.00000001.00000010. 11111110
Broadcast: 10.1.2.255 00001010.00000001.00000010. 11111111
Hosts/Net: 254 Class A, Private Internet
```
This gives us some additional information but also confirms (using a slightly
different notation) the conversion from decimal to binary and shows the range
of possible host addresses in this network.
While [`cidrhost`](/docs/job-specification/hcl2/functions/ipnet/cidrhost) allows calculating single host IP addresses,
`cidrsubnet` on the other hand creates a new network prefix _within_ the given
network prefix. In other words, it creates a subnet.
When we call `cidrsubnet` we also pass two additional arguments: `newbits` and
`netnum`. `newbits` decides how much longer the resulting prefix will be in
bits; in our example here we specified `4`, which means that the resulting
subnet will have a prefix length of 24 + 4 = 28 bits. We can imagine these
bits breaking down as follows:
```text
10 . 1 . 2 . ? 0
00001010 00000001 00000010 | XXXX | 0000
parent network | netnum | host
```
Four of the eight bits that were originally the "host number" are now being
repurposed as the subnet number. The network prefix no longer falls on an
exact octet boundary, so in effect we are now splitting the last decimal number
in the IP address into two parts, using half of it to represent the subnet
number and the other half to represent the host number.
The `netnum` argument then decides what number value to encode into those
four new subnet bits. In our current example we passed `15`, which is
represented in binary as `1111`, allowing us to fill in the `XXXX` segment
in the above:
```text
10 . 1 . 2 . 15 0
00001010 00000001 00000010 | 1111 | 0000
parent network | netnum | host
```
To convert this back into normal decimal notation we need to recombine the
two portions of the final octet. Converting `11110000` from binary to decimal
gives 240, which can then be combined with our new prefix length of 28 to
produce the result `10.1.2.240/28`. Again we can pass this prefix string to
`ipcalc` to visualize it:
```shell-session
$ ipcalc 10.1.2.240/28
Address: 10.1.2.240 00001010.00000001.00000010.1111 0000
Netmask: 255.255.255.240 = 28 11111111.11111111.11111111.1111 0000
Wildcard: 0.0.0.15 00000000.00000000.00000000.0000 1111
=>
Network: 10.1.2.240/28 00001010.00000001.00000010.1111 0000
HostMin: 10.1.2.241 00001010.00000001.00000010.1111 0001
HostMax: 10.1.2.254 00001010.00000001.00000010.1111 1110
Broadcast: 10.1.2.255 00001010.00000001.00000010.1111 1111
Hosts/Net: 14 Class A, Private Internet
```
The new subnet has four bits available for host numbering, which means
that there are 14 host addresses available for assignment once we subtract
the network's own address and the broadcast address. You can thus use
[`cidrhost`](/docs/job-specification/hcl2/functions/ipnet/cidrhost) function to calculate those host addresses by
providing it a value between 1 and 14:
```shell-session
> cidrhost("10.1.2.240/28", 1)
10.1.2.241
> cidrhost("10.1.2.240/28", 14)
10.1.2.254
```
For more information on CIDR notation and subnetting, see
[Classless Inter-domain Routing](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing).
## Related Functions
- [`cidrhost`](/docs/job-specification/hcl2/functions/ipnet/cidrhost) calculates the IP address for a single host
within a given network address prefix.
- [`cidrnetmask`](/docs/job-specification/hcl2/functions/ipnet/cidrnetmask) converts an IPv4 network prefix in CIDR
notation into netmask notation.
- [`cidrsubnets`](/docs/job-specification/hcl2/functions/ipnet/cidrsubnets) can allocate multiple consecutive
addresses under a prefix at once, numbering them automatically.

View File

@@ -0,0 +1,94 @@
---
layout: docs
page_title: cidrsubnets - Functions - Configuration Language
description: |-
The cidrsubnets function calculates a sequence of consecutive IP address
ranges within a particular CIDR prefix.
---
# `cidrsubnets` Function
`cidrsubnets` calculates a sequence of consecutive IP address ranges within
a particular CIDR prefix.
```hcl
cidrsubnets(prefix, newbits...)
```
`prefix` must be given in CIDR notation, as defined in
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
The remaining arguments, indicated as `newbits` above, each specify the number
of additional network prefix bits for one returned address range. The return
value is therefore a list with one element per `newbits` argument, each
a string containing an address range in CIDR notation.
For more information on IP addressing concepts, see the documentation for the
related function [`cidrsubnet`](/docs/job-specification/hcl2/functions/ipnet/cidrsubnet). `cidrsubnet` calculates
a single subnet address within a prefix while allowing you to specify its
subnet number, while `cidrsubnets` can calculate many at once, potentially of
different sizes, and assigns subnet numbers automatically.
When using this function to partition an address space as part of a network
address plan, you must not change any of the existing arguments once network
addresses have been assigned to real infrastructure, or else later address
assignments will be invalidated. However, you _can_ append new arguments to
existing calls safely, as long as there is sufficient address space available.
This function accepts both IPv6 and IPv4 prefixes, and the result always uses
the same addressing scheme as the given prefix.
## Examples
```shell-session
> cidrsubnets("10.1.0.0/16", 4, 4, 8, 4)
[
"10.1.0.0/20",
"10.1.16.0/20",
"10.1.32.0/24",
"10.1.48.0/20",
]
> cidrsubnets("fd00:fd12:3456:7890::/56", 16, 16, 16, 32)
[
"fd00:fd12:3456:7800::/72",
"fd00:fd12:3456:7800:100::/72",
"fd00:fd12:3456:7800:200::/72",
"fd00:fd12:3456:7800:300::/88",
]
```
You can use nested `cidrsubnets` calls with
[`for` expressions](/docs/job-specification/hcl2/expressions#for-expressions)
to concisely allocate groups of network address blocks:
```shell-session
> [for cidr_block in cidrsubnets("10.0.0.0/8", 8, 8, 8, 8) : cidrsubnets(cidr_block, 4, 4)]
[
[
"10.0.0.0/20",
"10.0.16.0/20",
],
[
"10.1.0.0/20",
"10.1.16.0/20",
],
[
"10.2.0.0/20",
"10.2.16.0/20",
],
[
"10.3.0.0/20",
"10.3.16.0/20",
],
]
```
## Related Functions
- [`cidrhost`](/docs/job-specification/hcl2/functions/ipnet/cidrhost) calculates the IP address for a single host
within a given network address prefix.
- [`cidrnetmask`](/docs/job-specification/hcl2/functions/ipnet/cidrnetmask) converts an IPv4 network prefix in CIDR
notation into netmask notation.
- [`cidrsubnet`](/docs/job-specification/hcl2/functions/ipnet/cidrsubnet) calculates a single subnet address, allowing
you to specify its network number.

View File

@@ -0,0 +1,23 @@
---
layout: docs
page_title: abs - Functions - Configuration Language
sidebar_title: abs
description: The abs function returns the absolute value of the given number.
---
# `abs` Function
`abs` returns the absolute value of the given number. In other words, if the
number is zero or positive then it is returned as-is, but if it is negative
then it is multiplied by -1 to make it positive before returning it.
## Examples
```shell-session
> abs(23)
23
> abs(0)
0
> abs(-12.4)
12.4
```

View File

@@ -0,0 +1,27 @@
---
layout: docs
page_title: ceil - Functions - Configuration Language
sidebar_title: ceil
description: |-
The ceil function returns the closest whole number greater than or equal to
the given value.
---
# `ceil` Function
`ceil` returns the closest whole number that is greater than or equal to the
given value, which may be a fraction.
## Examples
```shell-session
> ceil(5)
5
> ceil(5.1)
6
```
## Related Functions
- [`floor`](/docs/job-specification/hcl2/functions/numeric/floor), which rounds to the nearest whole number _less than_
or equal.

View File

@@ -0,0 +1,27 @@
---
layout: docs
page_title: floor - Functions - Configuration Language
sidebar_title: floor
description: |-
The floor function returns the closest whole number less than or equal to
the given value.
---
# `floor` Function
`floor` returns the closest whole number that is less than or equal to the
given value, which may be a fraction.
## Examples
```shell-session
> floor(5)
5
> floor(4.9)
4
```
## Related Functions
- [`ceil`](/docs/job-specification/hcl2/functions/numeric/ceil), which rounds to the nearest whole number _greater than_
or equal.

View File

@@ -0,0 +1,35 @@
---
layout: docs
page_title: log - Functions - Configuration Language
sidebar_title: log
description: The log function returns the logarithm of a given number in a given base.
---
# `log` Function
`log` returns the logarithm of a given number in a given base.
```hcl
log(number, base)
```
## Examples
```shell-session
> log(50, 10)
1.6989700043360185
> log(16, 2)
4
```
`log` and `ceil` can be used together to find the minimum number of binary
digits required to represent a given number of distinct values:
```shell-session
> ceil(log(15, 2))
4
> ceil(log(16, 2))
4
> ceil(log(17, 2))
5
```

View File

@@ -0,0 +1,29 @@
---
layout: docs
page_title: max - Functions - Configuration Language
sidebar_title: max
description: The max function takes one or more numbers and returns the greatest number.
---
# `max` Function
`max` takes one or more numbers and returns the greatest number from the set.
## Examples
```shell-session
> max(12, 54, 3)
54
```
If the numbers are in a list or set value, use `...` to expand the collection
to individual arguments:
```shell-session
> max([12, 54, 3]...)
54
```
## Related Functions
- [`min`](/docs/job-specification/hcl2/functions/numeric/min), which returns the _smallest_ number from a set.

View File

@@ -0,0 +1,29 @@
---
layout: docs
page_title: min - Functions - Configuration Language
sidebar_title: min
description: The min function takes one or more numbers and returns the smallest number.
---
# `min` Function
`min` takes one or more numbers and returns the smallest number from the set.
## Examples
```shell-session
> min(12, 54, 3)
3
```
If the numbers are in a list or set value, use `...` to expand the collection
to individual arguments:
```shell-session
> min([12, 54, 3]...)
3
```
## Related Functions
- [`max`](/docs/job-specification/hcl2/functions/numeric/max), which returns the _greatest_ number from a set.

View File

@@ -0,0 +1,52 @@
---
layout: docs
page_title: parseint - Functions - Configuration Language
sidebar_title: parseint
description: >-
The parseint function parses the given string as a representation of an
integer.
---
# `parseint` Function
`parseint` parses the given string as a representation of an integer in
the specified base and returns the resulting number. The base must be between 2
and 62 inclusive.
All bases use the arabic numerals 0 through 9 first. Bases between 11 and 36
inclusive use case-insensitive latin letters to represent higher unit values.
Bases 37 and higher use lowercase latin letters and then uppercase latin
letters.
If the given string contains any non-digit characters or digit characters that
are too large for the given base then `parseint` will produce an error.
## Examples
```shell-session
> parseint("100", 10)
100
> parseint("FF", 16)
255
> parseint("-10", 16)
-16
> parseint("1011111011101111", 2)
48879
> parseint("aA", 62)
656
> parseint("12", 2)
Error: Invalid function argument
Invalid value for "number" parameter: cannot parse "12" as a base 2 integer.
```
## Related Functions
- [`format`](/docs/job-specification/hcl2/functions/string/format) can format numbers and other values into strings,
with optional zero padding, alignment, etc.

View File

@@ -0,0 +1,19 @@
---
layout: docs
page_title: pow - Functions - Configuration Language
sidebar_title: pow
description: The pow function raises a number to a power.
---
# `pow` Function
`pow` calculates an exponent, by raising its first argument to the power of the second argument.
## Examples
```shell-session
> pow(3, 2)
9
> pow(4, 0)
1
```

View File

@@ -0,0 +1,22 @@
---
layout: docs
page_title: signum - Functions - Configuration Language
sidebar_title: signum
description: The signum function determines the sign of a number.
---
# `signum` Function
`signum` determines the sign of a number, returning a number between -1 and
1 to represent the sign.
## Examples
```shell-session
> signum(-13)
-1
> signum(0)
0
> signum(344)
1
```

View File

@@ -0,0 +1,29 @@
---
layout: docs
page_title: chomp - Functions - Configuration Language
sidebar_title: chomp
description: The chomp function removes newline characters at the end of a string.
---
# `chomp` Function
`chomp` removes newline characters at the end of a string.
This can be useful if, for example, the string was read from a file that has
a newline character at the end.
## Examples
```shell-session
> chomp("hello\n")
hello
> chomp("hello\r\n")
hello
> chomp("hello\n\n")
hello
```
## Related Functions
- [`trimspace`](/docs/job-specification/hcl2/functions/string/trimspace), which removes all types of whitespace from
both the start and the end of a string.

View File

@@ -0,0 +1,121 @@
---
layout: docs
page_title: format - Functions - Configuration Language
sidebar_title: format
description: |-
The format function produces a string by formatting a number of other values
according to a specification string.
---
# `format` Function
`format` produces a string by formatting a number of other values according
to a specification string. It is similar to the `printf` function in C, and
other similar functions in other programming languages.
```hcl
format(spec, values...)
```
## Examples
```shell-session
> format("Hello, %s!", "Ander")
Hello, Ander!
> format("There are %d lights", 4)
There are 4 lights
```
Simple format verbs like `%s` and `%d` behave similarly to template
interpolation syntax, which is often more readable:
```shell-session
> format("Hello, %s!", var.name)
Hello, Valentina!
> "Hello, ${var.name}!"
Hello, Valentina!
```
The `format` function is therefore more useful when you use more complex format
specifications, as described in the following section.
## Specification Syntax
The specification is a string that includes formatting verbs that are introduced
with the `%` character. The function call must then have one additional argument
for each verb sequence in the specification. The verbs are matched with
consecutive arguments and formatted as directed, as long as each given argument
is convertible to the type required by the format verb.
The specification may contain the following verbs:
| Verb | Result |
| ----- | ----------------------------------------------------------------------------------------- |
| `%%` | Literal percent sign, consuming no value. |
| `%v` | Default formatting based on the value type, as described below. |
| `%#v` | JSON serialization of the value, as with `jsonencode`. |
| `%t` | Convert to boolean and produce `true` or `false`. |
| `%b` | Convert to integer number and produce binary representation. |
| `%d` | Convert to integer number and produce decimal representation. |
| `%o` | Convert to integer number and produce octal representation. |
| `%x` | Convert to integer number and produce hexadecimal representation with lowercase letters. |
| `%X` | Like `%x`, but use uppercase letters. |
| `%e` | Convert to number and produce scientific notation, like `-1.234456e+78`. |
| `%E` | Like `%e`, but use an uppercase `E` to introduce the exponent. |
| `%f` | Convert to number and produce decimal fraction notation with no exponent, like `123.456`. |
| `%g` | Like `%e` for large exponents or like `%f` otherwise. |
| `%G` | Like `%E` for large exponents or like `%f` otherwise. |
| `%s` | Convert to string and insert the string's characters. |
| `%q` | Convert to string and produce a JSON quoted string representation. |
When `%v` is used, one of the following format verbs is chosen based on the value type:
| Type | Verb |
| --------- | ----- |
| `string` | `%s` |
| `number` | `%g` |
| `bool` | `%t` |
| any other | `%#v` |
Null values produce the string `null` if formatted with `%v` or `%#v`, and
cause an error for other verbs.
A width modifier can be included with an optional decimal number immediately
preceding the verb letter, to specify how many characters will be used to
represent the value. Precision can be specified after the (optional) width
with a period (`.`) followed by a decimal number. If width or precision are
omitted then default values are selected based on the given value. For example:
| Sequence | Result |
| -------- | ---------------------------- |
| `%f` | Default width and precision. |
| `%9f` | Width 9, default precision. |
| `%.2f` | Default width, precision 2. |
| `%9.2f` | Width 9, precision 2. |
The following additional symbols can be used immediately after the `%` symbol
to set additoinal flags:
| Symbol | Result |
| ------ | -------------------------------------------------------------- |
| space | Leave a space where the sign would be if a number is positive. |
| `+` | Show the sign of a number even if it is positive. |
| `-` | Pad the width with spaces on the left rather than the right. |
| `0` | Pad the width with leading zeros rather than spaces. |
By default, `%` sequences consume successive arguments starting with the first.
Introducing a `[n]` sequence immediately before the verb letter, where `n` is a
decimal integer, explicitly chooses a particular value argument by its
one-based index. Subsequent calls without an explicit index will then proceed
with `n`+1, `n`+2, etc.
The function produces an error if the format string requests an impossible
conversion or access more arguments than are given. An error is produced also
for an unsupported format verb.
## Related Functions
- [`formatdate`](/docs/job-specification/hcl2/functions/datetime/formatdate) is a specialized formatting function for
human-readable timestamps.
- [`formatlist`](/docs/job-specification/hcl2/functions/string/formatlist) uses the same specification syntax to
produce a list of strings.

View File

@@ -0,0 +1,51 @@
---
layout: docs
page_title: formatlist - Functions - Configuration Language
sidebar_title: formatlist
description: |-
The formatlist function produces a list of strings by formatting a number of
other values according to a specification string.
---
# `formatlist` Function
`formatlist` produces a list of strings by formatting a number of other
values according to a specification string.
```hcl
formatlist(spec, values...)
```
The specification string uses
[the same syntax as `format`](/docs/job-specification/hcl2/functions/string/format#specification-syntax).
The given values can be a mixture of list and non-list arguments. Any given
lists must be the same length, which decides the length of the resulting list.
The list arguments are iterated together in order by index, while the non-list
arguments are used repeatedly for each iteration. The format string is evaluated
once per element of the list arguments.
## Examples
```shell-session
> formatlist("Hello, %s!", ["Valentina", "Ander", "Olivia", "Sam"])
[
"Hello, Valentina!",
"Hello, Ander!",
"Hello, Olivia!",
"Hello, Sam!",
]
> formatlist("%s, %s!", "Salutations", ["Valentina", "Ander", "Olivia", "Sam"])
[
"Salutations, Valentina!",
"Salutations, Ander!",
"Salutations, Olivia!",
"Salutations, Sam!",
]
```
## Related Functions
- [`format`](/docs/job-specification/hcl2/functions/string/format) defines the specification syntax used by this
function and produces a single string as its result.

View File

@@ -0,0 +1,33 @@
---
layout: docs
page_title: indent - Functions - Configuration Language
sidebar_title: indent
description: |-
The indent function adds a number of spaces to the beginnings of all but the
first line of a given multi-line string.
---
# `indent` Function
`indent` adds a given number of spaces to the beginnings of all but the first
line in a given multi-line string.
```hcl
indent(num_spaces, string)
```
## Examples
This function is useful for inserting a multi-line string into an
already-indented context in another string:
```shell-session
> " items: %{indent(2, "[\n foo,\n bar,\n]\n")}"
items: [
foo,
bar,
]
```
The first line of the string is not indented so that, as above, it can be
placed after an introduction sequence that has already begun the line.

View File

@@ -0,0 +1,31 @@
---
layout: docs
page_title: join - Functions - Configuration Language
sidebar_title: join
description: |-
The join function produces a string by concatenating the elements of a list
with a given delimiter.
---
# `join` Function
`join` produces a string by concatenating together all elements of a given
list of strings with the given delimiter.
```hcl
join(separator, list)
```
## Examples
```shell-session
> join(", ", ["foo", "bar", "baz"])
foo, bar, baz
> join(", ", ["foo"])
foo
```
## Related Functions
- [`split`](/docs/job-specification/hcl2/functions/string/split) performs the opposite operation: producing a list
by separating a single string using a given delimiter.

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: lower - Functions - Configuration Language
sidebar_title: lower
description: >-
The lower function converts all cased letters in the given string to
lowercase.
---
# `lower` Function
`lower` converts all cased letters in the given string to lowercase.
## Examples
```shell-session
> lower("HELLO")
hello
> lower("АЛЛО!")
алло!
```
This function uses Unicode's definition of letters and of upper- and lowercase.
## Related Functions
- [`upper`](/docs/job-specification/hcl2/functions/string/upper) converts letters in a string to _uppercase_.
- [`title`](/docs/job-specification/hcl2/functions/string/title) converts the first letter of each word in a string to uppercase.

View File

@@ -0,0 +1,46 @@
---
layout: docs
page_title: regex_replace - Functions - Configuration Language
sidebar_title: regex_replace
description: |-
The regex_replace function searches a given string for another given substring,
and replaces all occurrences with a given replacement string. The substring
argument can be a valid regular expression or a string.
---
# `regex_replace` Function
`regex_replace` searches a given string for another given substring, and
replaces each occurrence with a given replacement string. The substring
argument can be a valid regular expression or a string.
```hcl
regex_replace(string, substring, replacement)
```
`substring` should not be wrapped in forward slashes, it is always treated as a
regular expression. The `replacement` string can incorporate captured strings
from the input by using an `$n` or `${n}` sequence, where `n` is the index or
name of a capture group.
## Examples
```shell-session
> regex_replace("hello world", "world", "everybody")
hello everybody
> regex_replace("hello world", "w.*d", "everybody")
hello everybody
> regex_replace("-ab-axxb-", "a(x*)b", "$1W)
---
> regex_replace("-ab-axxb-", "a(x*)b", "${1}W")
-W-xxW-
```
## Related Functions
- [`replace`](/docs/job-specification/hcl2/functions/string/replace) searches a given string for another given
substring, and replaces all occurrences with a given replacement string.

View File

@@ -0,0 +1,32 @@
---
layout: docs
page_title: replace - Functions - Configuration Language
sidebar_title: replace
description: |-
The replace function searches a given string for another given substring,
and replaces all occurrences with a given replacement string.
---
# `replace` Function
`replace` searches a given string for another given substring, and replaces
each occurrence with a given replacement string.
```hcl
replace(string, substring, replacement)
```
## Examples
```shell-session
> replace("1 + 2 + 3", "+", "-")
1 - 2 - 3
> replace("hello world", "world", "everybody")
hello everybody
```
## Related Functions
- [`regex_replace`](/docs/job-specification/hcl2/functions/string/regex_replace) searches a given string for another given substring,
and replaces each occurrence with a given replacement string.

View File

@@ -0,0 +1,41 @@
---
layout: docs
page_title: split - Functions - Configuration Language
sidebar_title: split
description: |-
The split function produces a list by dividing a given string at all
occurrences of a given separator.
---
# `split` Function
`split` produces a list by dividing a given string at all occurrences of a
given separator.
```hcl
split(separator, string)
```
## Examples
```shell-session
> split(",", "foo,bar,baz")
[
"foo",
"bar",
"baz",
]
> split(",", "foo")
[
"foo",
]
> split(",", "")
[
"",
]
```
## Related Functions
- [`join`](/docs/job-specification/hcl2/functions/string/join) performs the opposite operation: producing a string
joining together a list of strings with a given separator.

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: strrev - Functions - Configuration Language
sidebar_title: strrev
description: The strrev function reverses a string.
---
# `strrev` Function
`strrev` reverses the characters in a string.
Note that the characters are treated as _Unicode characters_ (in technical terms, Unicode [grapheme cluster boundaries](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) are respected).
```hcl
strrev(string)
```
## Examples
```shell-session
> strrev("hello")
olleh
> strrev("a ☃")
☃ a
```
## Related Functions
- [`reverse`](/docs/job-specification/hcl2/functions/collection/reverse) reverses a sequence.

View File

@@ -0,0 +1,31 @@
---
layout: docs
page_title: substr - Functions - Configuration Language
sidebar_title: substr
description: |-
The substr function extracts a substring from a given string by offset and
length.
---
# `substr` Function
`substr` extracts a substring from a given string by offset and length.
```hcl
substr(string, offset, length)
```
## Examples
```shell-session
> substr("hello world", 1, 4)
ello
```
The offset and length are both counted in _unicode characters_ rather than
bytes:
```shell-session
> substr("🤔🤷", 0, 1)
🤔
```

View File

@@ -0,0 +1,26 @@
---
layout: docs
page_title: title - Functions - Configuration Language
sidebar_title: title
description: |-
The title function converts the first letter of each word in a given string
to uppercase.
---
# `title` Function
`title` converts the first letter of each word in the given string to uppercase.
## Examples
```shell-session
> title("hello world")
Hello World
```
This function uses Unicode's definition of letters and of upper- and lowercase.
## Related Functions
- [`upper`](/docs/job-specification/hcl2/functions/string/upper) converts _all_ letters in a string to uppercase.
- [`lower`](/docs/job-specification/hcl2/functions/string/lower) converts all letters in a string to lowercase.

View File

@@ -0,0 +1,27 @@
---
layout: docs
page_title: trim - Functions - Configuration Language
sidebar_title: trim
description: |-
The trim function removes the specified characters from the start and end of
a given string.
---
# `trim` Function
`trim` removes the specified characters from the start and end of the given
string.
## Examples
```shell-session
> trim("?!hello?!", "!?")
hello
```
## Related Functions
- [`trimprefix`](/docs/job-specification/hcl2/functions/string/trimprefix) removes a word from the start of a string.
- [`trimsuffix`](/docs/job-specification/hcl2/functions/string/trimsuffix) removes a word from the end of a string.
- [`trimspace`](/docs/job-specification/hcl2/functions/string/trimspace) removes all types of whitespace from
both the start and the end of a string.

View File

@@ -0,0 +1,26 @@
---
layout: docs
page_title: trimprefix - Functions - Configuration Language
sidebar_title: trimprefix
description: |-
The trimprefix function removes the specified prefix from the start of a
given string.
---
# `trimprefix` Function
`trimprefix` removes the specified prefix from the start of the given string.
## Examples
```shell-session
> trimprefix("helloworld", "hello")
world
```
## Related Functions
- [`trim`](/docs/job-specification/hcl2/functions/string/trim) removes characters at the start and end of a string.
- [`trimsuffix`](/docs/job-specification/hcl2/functions/string/trimsuffix) removes a word from the end of a string.
- [`trimspace`](/docs/job-specification/hcl2/functions/string/trimspace) removes all types of whitespace from
both the start and the end of a string.

View File

@@ -0,0 +1,29 @@
---
layout: docs
page_title: trimspace - Functions - Configuration Language
sidebar_title: trimspace
description: |-
The trimspace function removes space characters from the start and end of
a given string.
---
# `trimspace` Function
`trimspace` removes any space characters from the start and end of the given
string.
This function follows the Unicode definition of "space", which includes
regular spaces, tabs, newline characters, and various other space-like
characters.
## Examples
```shell-session
> trimspace(" hello\n\n")
hello
```
## Related Functions
- [`chomp`](/docs/job-specification/hcl2/functions/string/chomp) removes just line ending characters from the _end_ of
a string.

View File

@@ -0,0 +1,26 @@
---
layout: docs
page_title: trimsuffix - Functions - Configuration Language
sidebar_title: trimsuffix
description: |-
The trimsuffix function removes the specified suffix from the end of a
given string.
---
# `trimsuffix` Function
`trimsuffix` removes the specified suffix from the end of the given string.
## Examples
```shell-session
> trimsuffix("helloworld", "world")
hello
```
## Related Functions
- [`trim`](/docs/job-specification/hcl2/functions/string/trim) removes characters at the start and end of a string.
- [`trimprefix`](/docs/job-specification/hcl2/functions/string/trimprefix) removes a word from the start of a string.
- [`trimspace`](/docs/job-specification/hcl2/functions/string/trimspace) removes all types of whitespace from
both the start and the end of a string.

View File

@@ -0,0 +1,28 @@
---
layout: docs
page_title: upper - Functions - Configuration Language
sidebar_title: upper
description: >-
The upper function converts all cased letters in the given string to
uppercase.
---
# `upper` Function
`upper` converts all cased letters in the given string to uppercase.
## Examples
```shell-session
> upper("hello")
HELLO
> upper("алло!")
АЛЛО!
```
This function uses Unicode's definition of letters and of upper- and lowercase.
## Related Functions
- [`lower`](/docs/job-specification/hcl2/functions/string/lower) converts letters in a string to _lowercase_.
- [`title`](/docs/job-specification/hcl2/functions/string/title) converts the first letter of each word in a string to uppercase.

View File

@@ -0,0 +1,29 @@
---
layout: docs
page_title: v4 - uuid - Functions - Configuration Language
sidebar_title: uuidv4
description: The uuidv4 function generates a unique id.
---
# `uuidv4` Function
`uuidv4` generates a unique identifier string.
The id is a generated and formatted as required by [RFC 4122 section
4.4](https://tools.ietf.org/html/rfc4122#section-4.4), producing a Version 4
UUID. The result is a UUID generated only from pseudo-random numbers.
This function produces a new value each time it is called, and so using it
directly in job arguments will result in spurious diffs. We do not
recommend using the `uuidv4` function in resource configurations.
## Examples
```shell-session
> uuidv4()
b5ee72a3-54dd-c4b8-551c-4bdc0204cedb
```
## Related Functions
- [`uuidv5`](/docs/job-specification/hcl2/functions/uuid/uuidv5), which generates name-based UUIDs.

View File

@@ -0,0 +1,80 @@
---
layout: docs
page_title: uuidv5 - Functions - Configuration Language
sidebar_title: uuidv5
description: |-
The uuidv5 function generates a uuid v5 string representation of the value in
the specified namespace.
---
# `uuidv5` Function
`uuidv5` generates a _name-based_ UUID, as described in [RFC 4122 section
4.3](https://tools.ietf.org/html/rfc4122#section-4.3), also known as a "version
5" UUID.
```hcl
uuidv5(namespace, name)
```
Unlike the pseudo-random UUIDs generated by [`uuidv4`](/docs/job-specification/hcl2/functions/uuid/uuidv4),
name-based UUIDs derive from namespace and an name, producing the same UUID
value every time if the namespace and name are unchanged.
Name-based UUID namespaces are themselves UUIDs, but for readability this
function accepts some keywords as aliases for the namespaces that were assigned
by RFC 4122:
| Keyword | Namespace ID | Name format |
| -------- | -------------------------------------- | ---------------------------------------------------------------------------- |
| `"dns"` | `6ba7b810-9dad-11d1-80b4-00c04fd430c8` | A fully-qualified DNS domain name. |
| `"url"` | `6ba7b811-9dad-11d1-80b4-00c04fd430c8` | Any valid URL as defined in [RFC 3986](https://tools.ietf.org/html/rfc3986). |
| `"oid"` | `6ba7b812-9dad-11d1-80b4-00c04fd430c8` | An [ISO/IEC object identifier](https://oidref.com/) |
| `"x500"` | `6ba7b814-9dad-11d1-80b4-00c04fd430c8` | [X.500 Distinguished Name](https://tools.ietf.org/html/rfc1779) |
To use any other namespace not included in the above table, pass its assigned
namespace ID directly in the first argument in the usual UUID string format.
## Examples
Use the namespace keywords where possible, to make the intent more obvious to
a future reader:
```shell-session
> uuidv5("dns", "nomadproject.io")
d2616d48-e1cb-5b87-8a8c-46355decc76a
> uuidv5("url", "https://nomadproject.io/")
a1572394-3948-5251-b0c7-b4ded43587b4
> uuidv5("oid", "1.3.6.1.4")
af9d40a5-7a36-5c07-b23a-851cd99fbfa5
> uuidv5("x500", "CN=Example,C=GB")
84e09961-4aa4-57f8-95b7-03edb1073253
```
The namespace keywords treated as equivalent to their corresponding namespace
UUIDs, and in some special cases it may be more appropriate to use the
UUID form:
```shell-session
> uuidv5("6ba7b810-9dad-11d1-80b4-00c04fd430c8", "nomadproject.io")
d2616d48-e1cb-5b87-8a8c-46355decc76a
```
If you wish to use a namespace defined outside of RFC 4122, using the namespace
UUID is required because no corresponding keyword is available:
```shell-session
> uuidv5("743ac3c0-3bf7-4a5b-9e6c-59360447c757", "LIBS:diskfont.library")
ede1a974-df7e-5f17-84b9-76208818b2c8
```
When using raw UUID namespaces, consider including a comment alongside the
expression that indicates which namespace this represents in a
human-significant manner, such as by reference to the standard that defined it.
## Related Functions
- [`uuidv4`](/docs/job-specification/hcl2/functions/uuid/uuidv4), which generates pseudorandom UUIDs.

View File

@@ -0,0 +1,115 @@
---
layout: docs
page_title: Configuration Language
sidebar_title: HCL2 <sup>Beta</sup>
description: |-
Noamd uses text files to describe infrastructure and to set variables.
These text files are called Nomad job specifications and are
written in the HCL language.
---
# HCL <sup>Beta</sup>
`@include 'beta-nomad1.0-note.mdx'`
Nomad uses the Hashicorp Configuration Language - HCL - designed to allow
concise descriptions of the required steps to get to a job file.
Nomad 1.0 adopts
[HCL2](https://github.com/hashicorp/hcl2/blob/master/README.md), the second
generation of HashiCorp Configuration Language. HCL2 extends the HCL language by
adding expressions and input variables support to improve job spec
reusability and readability. Also, the new HCL2 parser improves the error
messages for invalid jobs.
<!---
TODO: Re-Add after guide
This page describes the features of HCL2 exhaustively, if you would like to give
a quick try to HCL2, you can also read the quicker [HCL2 getting started
guide](/guides/hcl).
--->
## Syntax
The main purpose of the HCL language in Nomad is defining jobs. All other
language features exist only to make the definition of builds more flexible and
convenient.
## Arguments, Blocks, and Expressions
The syntax of the HCL language consists of only a few basic elements:
```hcl
task "example" {
driver = "docker"
}
<BLOCK TYPE> "<BLOCK LABEL>" {
# Block body
<IDENTIFIER> = <EXPRESSION> # Argument
}
```
- _Blocks_ are containers for other content and usually represent the
configuration of some kind of object, like a task. Blocks have a
_block type,_ can have zero or more _labels,_ and have a _body_ that contains
any number of arguments and nested blocks.
- _Arguments_ assign a value to a name. They appear within blocks.
- _Expressions_ represent a value, either literally or by referencing and
combining other values. They appear as values for arguments, or within other
expressions.
For full details about Nomad's syntax, see:
- [Configuration Syntax](/docs/job-specification/hcl2/syntax)
- [Expressions](/docs/job-specification/hcl2/expressions)
## Backward Compatibilities
HCL2 syntax closely mirrors HCL1, but has some minor changes. Most existing
Nomad job specifications will not require any changes.
When you run `nomad job run` or `nomad job plan`, the CLI will report any
required changes. Also, you can activate a backwards compatibility mode by
passing `-hcl1` to use Nomad's HCL1 parser instead.
### Blocks
Nomad 0.12 and earlier allowed a few variations for defining blocks. For example, the following variations of `meta` were accepted:
```hcl
meta {
# meta attributes can be quoted or not
"team" = "..."
organization = "..."
}
# meta can be an assignment to a map
meta = { "team" = "...", organization = "..." }
```
Starting with Nomad 1.0 and the HCL2 parser, only the block syntax with unquoted attributes is accepted:
```hcl
meta {
team = "..."
organization = "..."
}
```
### Multiline "here doc" strings
Nomad supports multi-line string literals in the so-called "heredoc" style, inspired by Unix shell languages:
```hcl
template {
data = <<EOF
hello
world
EOF
}
```
HCL2 trims the whitespace preceeding the delimiter in the last line. So in the
above example, `data` is read as `"hello\n world\n "` in HCL1, but `"hello\n
world\n"` (note lack of trailing whitespace) in HCL2.

View File

@@ -0,0 +1,53 @@
---
layout: docs
page_title: Local Values - HCL Configuration Language
sidebar_title: Locals
description: >-
Local values assign a name to an expression that can then be used multiple
times within a folder.
---
# Local Values
`@include 'beta-nomad1.0-note.mdx'`
Local values assign a name to an expression, that can then be used multiple
times within a folder.
If [variables](/docs/job-specification/hcl2/variables) are analogous to function arguments then
_local values_ are comparable to a function's local variables.
## Examples
Local values are defined in `locals` blocks:
```hcl
# A computed default name prefix
locals {
default_name_prefix = "${var.project_name}-web"
name_prefix = "${var.name_prefix != "" ? var.name_prefix : local.default_name_prefix}"
}
# Local values can be interpolated elsewhere using the "local." prefix.
job "${local.name_prefix}_loadbalancer" {
# ...
}
```
## Description
The `locals` block defines one or more local variables.
The names given for the items in the `locals` block must be unique. The given
value can be any expression that is valid within the current file.
The expression of a local value can refer to other locals, but reference cycles
are not allowed. That is, a local cannot refer to itself or to a variable that
refers (directly or indirectly) back to it.
It's recommended to group together logically-related local values into a single
block, particularly if they depend on each other. This will help the reader
understand the relationships between variables. Conversely, prefer to define
_unrelated_ local values in _separate_ blocks, and consider annotating each
block with a comment describing any context common to all of the enclosed
locals.

View File

@@ -0,0 +1,117 @@
---
layout: docs
page_title: Syntax - Configuration Language
sidebar_title: Syntax
description: |-
HCL has its own syntax, intended to combine declarative
structure with expressions in a way that is easy for humans to read and
understand.
---
# HCL Configuration Syntax
`@include 'beta-nomad1.0-note.mdx'`
Other pages in this section have described various configuration constructs
that can appear in HCL. This page describes the lower-level syntax of the
language in more detail, revealing the building blocks that those constructs
are built from.
This page describes the _native syntax_ of HCL, which is a rich language
designed to be easy for humans to read and write.
This low-level syntax of HCL is defined in terms of a syntax called _HCL_,
which is also used by configuration languages in other applications, and in
particular other HashiCorp products. It is not necessary to know all of the
details of HCL in order to use Nomad, and so this page summarizes the most
important details. If you are interested, you can find a full definition of HCL
syntax in [the HCL native syntax
specification](https://github.com/hashicorp/hcl/blob/hcl2/hclsyntax/spec.md).
## Arguments and Blocks
HCL syntax is built around two key syntax constructs:
arguments and blocks.
### Arguments
An _argument_ assigns a value to a particular name:
```hcl
image_id = "nginx:1.19"
```
The identifier before the equals sign is the _argument name_, and the expression
after the equals sign is the argument's value.
The context where the argument appears determines what value types are valid
(for example, each job block type has a schema that defines the types of its
arguments), but many arguments accept arbitrary
[expressions](/docs/job-specification/hcl2/expressions), which allow the value to
either be specified literally or generated from other values programmatically.
### Blocks
A _block_ is a container for other content:
```hcl
task "webserver" {
driver = "docker"
config {
# ...
}
}
```
A block has a _type_ (`task` in this example). Each block type defines
how many _labels_ must follow the type keyword. The `task` block type
expects one labels, which is `webserver` in the example above.
A particular block type may have any number of required labels, or it may
require none as with the nested `config` block type.
After the block type keyword and any labels, the block _body_ is delimited
by the `{` and `}` characters. Within the block body, further arguments
and blocks may be nested, creating a hierarchy of blocks and their associated
arguments.
HCL uses a limited number of _top-level block types,_ which
are blocks that can appear outside of any other block in a configuration file.
## Identifiers
Argument names, block type names, and the names of most Nomad-specific
constructs like tasks, input variables, etc. are all _identifiers_.
Identifiers can contain letters, digits, underscores (`_`), and hyphens (`-`).
The first character of an identifier must not be a digit, to avoid ambiguity
with literal numbers.
For complete identifier rules, Nomad implements
[the Unicode identifier syntax](http://unicode.org/reports/tr31/), extended to
include the ASCII hyphen character `-`.
## Comments
HCL supports three different syntaxes for comments:
- `#` begins a single-line comment, ending at the end of the line.
- `//` also begins a single-line comment, as an alternative to `#`.
- `/*` and `*/` are start and end delimiters for a comment that might span
over multiple lines.
The `#` single-line comment style is the default comment style and should be
used in most cases. Automatic configuration formatting tools may automatically
transform `//` comments into `#` comments, since the double-slash style is
not idiomatic.
## Character Encoding and Line Endings
Nomad configuration files must always be UTF-8 encoded. While the
delimiters of the language are all ASCII characters, Nomad accepts
non-ASCII characters in identifiers, comments, and string values.
Nomad accepts configuration files with either Unix-style line endings
(LF only) or Windows-style line endings (CR then LF), but the idiomatic style
is to use the Unix convention, and so automatic configuration formatting tools
may automatically transform CRLF endings to LF.

View File

@@ -0,0 +1,302 @@
---
layout: docs
page_title: Input Variables - HCL Configuration Language
sidebar_title: Variables
description: |-
Input variables are parameters for Nomad jobs.
This page covers configuration syntax for variables.
---
# Input Variables
`@include 'beta-nomad1.0-note.mdx'`
Input variables serve as parameters for a Nomad job, allowing aspects of the
job to be customized without altering the job's own source code.
When you declare variables in the job configuration, you can set
their values using CLI options and environment variables.
-> **Note:** For brevity, input variables are often referred to as just
"variables" or "Nomad variables" when it is clear from context what sort of
variable is being discussed. Other kinds of variables in Nomad include
_environment variables_ (set by the shell where Nomad runs) and _expression
variables_ (used to indirectly represent a value in an
[expression](/docs/job-specification/hcl2/expressions)).
## Declaring an Input Variable
Each input variable accepted by a job must be declared using a `variable`
block :
```hcl
variable "image_id" {
type = string
}
variable "availability_zone_names" {
type = list(string)
default = ["us-west-1a"]
}
variable "docker_ports" {
type = list(object({
internal = number
external = number
protocol = string
}))
default = [
{
internal = 8300
external = 8300
protocol = "tcp"
}
]
}
```
Or a less precise variables block:
```hcl
variables {
foo = "value"
my_secret = "foo"
}
```
The label after the `variable` keyword or a label of a `variables` block is a
name for the variable, which must be unique among all variables in the same
job. This name is used to assign a value to the variable from outside and to
reference the variable's value from within the job.
The `variable` block can optionally include a `type` argument to specify what
value types are accepted for the variable, as described in the following
section.
The `variable` declaration can also include a `default` argument. If present,
the variable is considered to be _optional_ and the default value will be used
if no value is set when calling the job or running Nomad. The `default`
argument requires a literal value and cannot reference other objects in the
configuration.
## Using Input Variable Values
Within the job that declared a variable, its value can be accessed from
within [expressions](/docs/job-specification/hcl2/expressions) as `var.<NAME>`, where `<NAME>`
matches the label given in the declaration block:
```hcl
config {
image = var.task_image
label = var.task_labels
}
```
The value assigned to a variable can be accessed only from expressions within
the folder where it was declared.
## Type Constraints
The `type` argument in a `variable` block allows you to restrict the [type of
value](/docs/job-specification/hcl2/expressions#types-and-values) that will be accepted as the value
for a variable. If no type constraint is set then a value of any type is
accepted.
While type constraints are optional, we recommend specifying them; they serve
as easy reminders for users of the job, and allow Nomad to return a helpful
error message if the wrong type is used.
Type constraints are created from a mixture of type keywords and type
constructors. The supported type keywords are:
- `string`
- `number`
- `bool`
The type constructors allow you to specify complex types such as collections:
- `list(<TYPE>)`
- `set(<TYPE>)`
- `map(<TYPE>)`
- `object({<ATTR NAME> = <TYPE>, ... })`
- `tuple([<TYPE>, ...])`
The keyword `any` may be used to indicate that any type is acceptable. For more
information on the meaning and behavior of these different types, as well as
detailed information about automatic conversion of complex types, see [Type
Constraints](https://www.terraform.io/docs/configuration/types.html).
If both the `type` and `default` arguments are specified, the given default
value must be convertible to the specified type.
If only `default` is specified, the type of the default value will be used.
When the `type` and `default` are both _not_ specified and you try to set a
variable [from env vars](#environment-variables) or [from the command
line](#variables-on-the-command-line), the variable will always be interpreted
as a string.
## Input Variable Documentation
Because the input variables of a job are part of its user interface, you can
briefly describe the purpose of each variable using the optional `description`
argument:
```hcl
variable "image_id" {
type = string
description = "The docker image used for task."
}
```
The description should concisely explain the purpose of the variable and what
kind of value is expected. This description string might be included in
documentation about the job, and so it should be written from the perspective
of the user of the job rather than its maintainer. For commentary for job
maintainers, use comments.
## Assigning Values to job Variables
Once a variable is declared in your configuration, you can set it:
- Individually, with the `-var foo=bar` command line option.
- In variable definitions files specified on the command line (with `-var-file=input.vars`).
- As environment variables, for example: `NOMAD_VAR_foo=bar`
The following sections describe these options in more detail.
### Variables on the Command Line
To specify individual variables on the command line, use the `-var` option when
running the `nomad job run` command:
```shell-session
$ nomad job run -var="image_id=nginx:1.19" example.nomad
```
The `-var` option can be used any number of times in a single command.
If you plan to assign variables via the command line, we strongly recommend that
you at least set a default type instead of using empty blocks; this helps the
HCL parser understand what is being set. Otherwise, the interpreter will assume
that any variable set on the command line is a string.
### Variable Definitions Files
To set lots of variables, it is more convenient to specify their values in a
_variable definitions file_ and then specify that file on the command line with
`-var-file`:
```shell-session
$ nomad job run -var-file="testing.vars" example.nomad
```
A variable definitions file uses the same HCL basic syntax, but consists only
of variable name assignments:
```hcl
image_id = "nginx:1.19"
labels = [
"testing",
"internal",
]
```
Alternatively, the files can be JSON objects, with the root object properties
corresponding to variable names:
```json
{
"image_id": "nginx:1.19",
"labels": ["testing", "internal"],
}
```
### Environment Variables
As a fallback for the other ways of defining variables, Nomad searches the
environment of its own process for environment variables named `NOMAD_VAR_`
followed by the name of a declared variable.
This can be useful when running Nomad in automation, or when running a
sequence of Nomad commands in succession with the same variables. For example,
at a `bash` prompt on a Unix system:
```shell-session
$ export NOMAD_VAR_image_id=nginx:1.19
$ nomad job run example.nomad
...
```
On operating systems where environment variable names are case-sensitive,
Nomad matches the variable name exactly as given in configuration, and so the
required environment variable name will usually have a mix of upper and lower
case letters as in the above example.
### Complex-typed Values
When variable values are provided in a variable definitions file, Nomad's
[usual syntax](/docs/job-specification/hcl2/expressions) can be used to assign
complex-typed values, like lists and maps.
Some special rules apply to the `-var` command line option and to environment
variables. For convenience, Nomad defaults to interpreting `-var` and
environment variable values as literal strings, which do not need to be quoted:
```shell-session
$ export NOMAD_VAR_image_id=nginx:1.19
```
However, if an input variable uses a [type constraint](#type-constraints) to
require a complex value (list, set, map, object, or tuple), Nomad will instead
attempt to parse its value using the same syntax used within variable
definitions files, which requires careful attention to the string escaping
rules in your shell:
```shell-session
$ export NOMAD_VAR_availability_zone_names='["us-west-1b","us-west-1d"]'
```
For readability, and to avoid the need to worry about shell escaping, we
recommend always setting complex variable values via variable definitions
files.
### Variable Definition Precedence
The above mechanisms for setting variables can be used together in any
combination.
Nomad loads variables in the following order, with later sources taking
precedence over earlier ones:
- Environment variables (lowest priority)
- Any `-var` and `-var-file` options on the command line, in the order they are
provided. (highest priority)
If the same variable is assigned multiple values using different mechanisms,
Nomad uses the _last_ value it finds, overriding any previous values. Note
that the same variable cannot be assigned multiple values within a single source.
~> **Important:** Variables with map and object values behave the same way as
other variables: the last value found overrides the previous values.
## A variable value must be known:
Take the following variable for example:
```hcl
variable "foo" {
type = string
}
```
Here `foo` must have a known value but you can default it to `null` to make
this behavior optional :
| | no default | `default = null` | `default = "xy"` |
| :-----------------------------: | :--------------------------: | :--------------: | :--------------: |
| foo unused | error, "foo needs to be set" | - | - |
| var.foo | error, "foo needs to be set" | null | xy |
| `NOMAD_VAR_foo=yz`<br />var.foo | yz | yz | yz |
| `-var foo=yz`<br />var.foo | yz | yz | yz |

View File

@@ -0,0 +1 @@
~> **NOTE:** This page is about Nomad 1.0 Beta. Details are subject to change before final release.