From 8da3d269b08fe13e4dddb49a0dffff37c4d3f852 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 6 Jun 2019 13:28:54 -0700 Subject: [PATCH] website: Further elaboration on the "any" type constraint There have been a few questions about this so far which indicated that the previous docs for this feature were very lacking. This is an attempt to describe more completely what "any" means, and in particular that it isn't actually a type at all but rather a placeholder for a type to be selected dynamically. --- website/docs/configuration/types.html.md | 55 ++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/website/docs/configuration/types.html.md b/website/docs/configuration/types.html.md index 39261c1b3..1751169ca 100644 --- a/website/docs/configuration/types.html.md +++ b/website/docs/configuration/types.html.md @@ -59,10 +59,6 @@ a valid representation of a number or boolean value. * `false` converts to `"false"`, and vice-versa * `15` converts to `"15"`, and vice-versa -## The "Any" Type - -The type keyword `any` is a special type constraint that accepts any value. - ## Complex Types A _complex_ type is a type that groups multiple values into a single value. @@ -206,3 +202,54 @@ On the other hand, automatic conversion will fail if the provided value an argument requires a type of `map(string)` and a user provides the object `{name = ["Kristy", "Claudia", "Mary Anne", "Stacey"], age = 12}`, Terraform will raise a type mismatch error, since a tuple cannot be converted to a string. + +## Dynamic Types: The "any" Constraint + +The keyword `any` is a special construct that serves as a placeholder for a +type yet to be decided. `any` is not _itself_ a type: when interpreting a +value against a type constraint containing `any`, Terraform will attempt to +find a single actual type that could replace the `any` keyword to produce +a valid result. + +For example, given the type constraint `list(any)`, Terraform will examine +the given value and try to choose a replacement for the `any` that would +make the result valid. + +If the given value were `["a", "b", "c"]` -- whose physical type is +`tuple([string, string, string])`, Terraform analyzes this as follows: + +* Tuple types and list types are _similar_ per the previous section, so the + tuple-to-list conversion rule applies. +* All of the elements in the tuple are strings, so the type constraint + `string` would be valid for all of the list elements. +* Therefore in this case the `any` argument is replaced with `string`, + and the final concrete value type is `list(string)`. + +All of the elements of a collection must have the same type, so conversion +to `list(any)` requires that all of the given elements must be convertible +to a common type. This implies some other behaviors that result from the +conversion rules described in earlier sections. + +* If the given value were instead `["a", 1, "b"]` then Terraform would still + select `list(string)`, because of the primitive type conversion rules, and + the resulting value would be `["a", "1", "b"]` due to the string conversion + implied by that type constraint. +* If the given value were instead `["a", [], "b"]` then the value cannot + conform to the type constraint: there is no single type that both a string + and an empty tuple can convert to. Terraform would reject this value, + complaining that all elements must have the same type. + +Although the above examples use `list(any)`, a similar principle applies to +`map(any)` and `set(any)`. + +If you wish to apply absolutely no constraint to the given value, the `any` +keyword can be used in isolation: + +```hcl +variable "no_type_constraint" { + type = any +} +``` + +In this case, Terraform will replace `any` with the exact type of the given +value and thus perform no type conversion whatsoever.