Collection functions
Lists preserve order; maps use sorted string keys; sets deduplicate and sort deterministically. Most sequence functions accept lists or sets. These are ordinary compile-time values, not resource expansion syntax.
| Function | Result and rules |
|---|---|
alltrue(values) | True if every element is true; an empty collection returns true. Boolean strings are accepted; null is false. |
anytrue(values) | True if any element is true; an empty collection returns false. Boolean strings are accepted; null is false. |
chunklist(values, size) | Split into lists of positive integer size; the last may be shorter. |
coalesce(values...) | First nonnull, nonempty-string value after primitive type unification; no candidate fails. |
coalescelist(lists...) | First nonempty list or set; all arguments must be collections and no candidate fails. |
compact(strings) | Remove null and empty strings. |
concat(lists...) | Concatenate at least two lists/sets. |
contains(values, value) | Boolean membership using typed value identity. |
distinct(values) | Remove duplicate values, retaining first-occurrence order and merged annotations. |
element(values, index) | Wrap an integer index modulo the length, including negative indices; empty collections fail. |
flatten(values) | Recursively flatten nested lists; does not flatten collections inside objects. |
index(values, value) | First matching zero-based index; absent values fail. |
keys(map) | Sorted list of keys. Sensitive values alone do not make public keys sensitive. |
length(value) | String grapheme count or collection element or member count. |
lookup(map, key[, default]) | Member or explicit default; missing key without a default fails. Arguments evaluate eagerly. |
matchkeys(values, keys, search) | Select values whose corresponding keys occur in search; values and keys lengths must agree. |
merge(maps...) | Shallow merge; later values win. Zero arguments returns an empty map. Overwritten annotations survive. |
one(values) | Null for zero elements, the value for one, error for more. |
range([start,] limit[, step]) | List ending before limit; defaults start=0 and step=1 ascending/-1 descending. Finite fractional ranges are accepted; integer-only ranges preserve precision. Direction and nonzero step must be valid; at most 1024 values. |
reverse(values) | Reverse the sequence. |
setintersection(sets...) | Deterministic set containing values present in every argument. |
setproduct(collections...) | Cartesian product of at least two collections, returned as a list of positional lists. |
setsubtract(left, right) | Deterministic set of left values absent from right. |
setunion(sets...) | Deterministic deduplicated union. |
slice(values, start, end) | Half-open sequence range; invalid or negative bounds fail. |
sort(strings) | List sorted lexically; values must be strings. |
sum(numbers) | Sum a nonempty collection; integer-only sums preserve integer precision and reject overflow. |
transpose(map_of_string_lists) | Map each listed string to a sorted list of original keys. |
values(map) | Values in sorted key order. |
zipmap(keys, values) | Map corresponding equal-length lists; keys must be strings and later duplicate keys win. |
merge is shallow; data hierarchy deep merge is a separate input-resolution policy. toset, tolist, and tomap are documented under conversion. Set operations return sets, while setproduct returns lists. Size bounds apply during expansion.
Example
locals {collections = {all = alltrue([true, "true"])any = anytrue([false, true])chunks = chunklist([1, 2, 3], 2)chosen = coalesce(null, "", "app")nonempty = coalescelist([], ["app"])compacted = compact(["", null, "app"])combined = concat([1], [2])contains = contains(["app", "ops"], "app")distinct = distinct(["app", "app", "ops"])wrapped = element(["app", "ops"], 2)flat = flatten([[1], [2, [3]]])position = index(["app", "ops"], "ops")keys = keys({ app = 1, ops = 2 })size = length("rivet")fallback = lookup({ app = "ready" }, "ops", "missing")matched = matchkeys(["a", "b"], ["app", "ops"], ["ops"])merged = merge({ port = 80 }, { port = 443 })single = one(["app"])slots = range(0, 3)reversed = reverse([1, 2])common = setintersection(["app", "ops"], ["app"])product = setproduct(["app", "ops"], ["primary"])difference = setsubtract(["app", "ops"], ["ops"])union = setunion(["app"], ["app", "ops"])sliced = slice([1, 2, 3], 0, 2)sorted = sort(["ops", "app"])total = sum([1, 2, 3])inverted = transpose({ app = ["web"], ops = ["web"] })values = values({ app = 1, ops = 2 })zipped = zipmap(["app", "ops"], [1, 2])}}output "collections" {type = stringvalue = jsonencode(local.collections)}
All calls obey the function limits and annotation rules.