diff --git a/config/interpolate_funcs_test.go b/config/interpolate_funcs_test.go index 8bd03b111..46a6eba75 100644 --- a/config/interpolate_funcs_test.go +++ b/config/interpolate_funcs_test.go @@ -890,6 +890,57 @@ func TestInterpolateFuncKeys(t *testing.T) { }) } +// Confirm that keys return in sorted order, and values return in the order of +// their sorted keys. +func TestInterpolateFuncKeyValOrder(t *testing.T) { + testFunction(t, testFunctionConfig{ + Vars: map[string]ast.Variable{ + "var.foo": ast.Variable{ + Type: ast.TypeMap, + Value: map[string]ast.Variable{ + "D": ast.Variable{ + Value: "2", + Type: ast.TypeString, + }, + "C": ast.Variable{ + Value: "Y", + Type: ast.TypeString, + }, + "A": ast.Variable{ + Value: "X", + Type: ast.TypeString, + }, + "10": ast.Variable{ + Value: "Z", + Type: ast.TypeString, + }, + "1": ast.Variable{ + Value: "4", + Type: ast.TypeString, + }, + "3": ast.Variable{ + Value: "W", + Type: ast.TypeString, + }, + }, + }, + }, + Cases: []testFunctionCase{ + { + `${keys(var.foo)}`, + []interface{}{"1", "10", "3", "A", "C", "D"}, + false, + }, + + { + `${values(var.foo)}`, + []interface{}{"4", "Z", "W", "X", "Y", "2"}, + false, + }, + }, + }) +} + func TestInterpolateFuncValues(t *testing.T) { testFunction(t, testFunctionConfig{ Vars: map[string]ast.Variable{ diff --git a/website/source/docs/configuration/interpolation.html.md b/website/source/docs/configuration/interpolation.html.md index 6b38c7807..47b21b719 100644 --- a/website/source/docs/configuration/interpolation.html.md +++ b/website/source/docs/configuration/interpolation.html.md @@ -161,6 +161,8 @@ The supported built-in functions are: Note that if the item is a string, the return value includes the double quotes. + * `keys(map)` - Returns a lexically sorted, JSON-encoded list of the map keys. + * `length(list)` - Returns a number of members in a given list or a number of characters in a given string. * `${length(split(",", "a,b,c"))}` = 3 @@ -218,6 +220,8 @@ The supported built-in functions are: * `uuid()` - Returns a UUID string in RFC 4122 v4 format. This string will change with every invocation of the function, so in order to prevent diffs on every plan & apply, it must be used with the [`ignore_changes`](/docs/configuration/resources.html#ignore-changes) lifecycle attribute. + * `values(map)` - Returns a JSON-encoded list of the map values, in the order of the keys returned by the `keys` function. + ## Templates Long strings can be managed using templates. [Templates](/docs/providers/template/index.html) are [resources](/docs/configuration/resources.html) defined by a filename and some variables to use during interpolation. They have a computed `rendered` attribute containing the result.