github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/website/docs/configuration/types.html.md (about) 1 --- 2 layout: "docs" 3 page_title: "Type Constraints - Configuration Language" 4 sidebar_current: "docs-config-types" 5 description: |- 6 Terraform module authors and provider developers can use detailed type 7 constraints to validate the inputs of their modules and resources. 8 --- 9 10 # Type Constraints 11 12 -> **Note:** This page is about Terraform 0.12 and later, and documents a 13 feature that did not exist in older versions. For other information about 14 Terraform 0.11 and earlier, see 15 [0.11 Configuration Language](../configuration-0-11/index.html). 16 17 Terraform module authors and provider developers can use detailed type 18 constraints to validate user-provided values for their input variables and 19 resource arguments. This requires some additional knowledge about Terraform's 20 type system, but allows you to build a more resilient user interface for your 21 modules and resources. 22 23 ## Type Keywords and Constructors 24 25 Type constraints are expressed using a mixture of _type keywords_ and 26 function-like constructs called _type constructors._ 27 28 * Type keywords are unquoted symbols that represent a static type. 29 * Type constructors are unquoted symbols followed by a pair of 30 parentheses, which contain an argument that specifies more information about 31 the type. Without its argument, a type constructor does not fully 32 represent a type; instead, it represents a _kind_ of similar types. 33 34 Type constraints look like other kinds of Terraform 35 [expressions](./expressions.html), but are a special syntax. Within the 36 Terraform language, they are only valid in the `type` argument of an 37 [input variable](./variables.html). 38 39 ## Primitive Types 40 41 A _primitive_ type is a simple type that isn't made from any other types. All 42 primitive types in Terraform are represented by a type keyword. The available 43 primitive types are: 44 45 * `string`: a sequence of Unicode characters representing some text, such 46 as `"hello"`. 47 * `number`: a numeric value. The `number` type can represent both whole 48 numbers like `15` and fractional values such as `6.283185`. 49 * `bool`: either `true` or `false`. `bool` values can be used in conditional 50 logic. 51 52 ### Conversion of Primitive Types 53 54 The Terraform language will automatically convert `number` and `bool` values 55 to `string` values when needed, and vice-versa as long as the string contains 56 a valid representation of a number or boolean value. 57 58 * `true` converts to `"true"`, and vice-versa 59 * `false` converts to `"false"`, and vice-versa 60 * `15` converts to `"15"`, and vice-versa 61 62 ## Complex Types 63 64 A _complex_ type is a type that groups multiple values into a single value. 65 Complex types are represented by type constructors, but several of them 66 also have shorthand keyword versions. 67 68 There are two categories of complex types: collection types (for grouping 69 similar values), and structural types (for grouping potentially dissimilar 70 values). 71 72 ### Collection Types 73 74 A _collection_ type allows multiple values of _one_ other type to be grouped 75 together as a single value. The type of value _within_ a collection is called 76 its _element type._ All collection types must have an element type, which is 77 provided as the argument to their constructor. 78 79 For example, the type `list(string)` means "list of strings", which is a 80 different type than `list(number)`, a list of numbers. All elements of a 81 collection must always be of the same type. 82 83 The three kinds of collection type in the Terraform language are: 84 85 * `list(...)`: a sequence of values identified by consecutive whole numbers 86 starting with zero. 87 88 The keyword `list` is a shorthand for `list(any)`, which accepts any 89 element type as long as every element is the same type. This is for 90 compatibility with older configurations; for new code, we recommend using 91 the full form. 92 * `map(...)`: a collection of values where each is identified by a string label. 93 94 The keyword `map` is a shorthand for `map(any)`, which accepts any 95 element type as long as every element is the same type. This is for 96 compatibility with older configurations; for new code, we recommend using 97 the full form. 98 * `set(...)`: a collection of unique values that do not have any secondary 99 identifiers or ordering. 100 101 ### Structural Types 102 103 A _structural_ type allows multiple values of _several distinct types_ to be 104 grouped together as a single value. Structural types require a _schema_ as an 105 argument, to specify which types are allowed for which elements. 106 107 The two kinds of structural type in the Terraform language are: 108 109 * `object(...)`: a collection of named attributes that each have their own type. 110 111 The schema for object types is `{ <KEY> = <TYPE>, <KEY> = <TYPE>, ... }` — a 112 pair of curly braces containing a comma-separated series of `<KEY> = <TYPE>` 113 pairs. Values that match the object type must contain _all_ of the specified 114 keys, and the value for each key must match its specified type. (Values with 115 _additional_ keys can still match an object type, but the extra attributes 116 are discarded during type conversion.) 117 * `tuple(...)`: a sequence of elements identified by consecutive whole 118 numbers starting with zero, where each element has its own type. 119 120 The schema for tuple types is `[<TYPE>, <TYPE>, ...]` — a pair of square 121 brackets containing a comma-separated series of types. Values that match the 122 tuple type must have _exactly_ the same number of elements (no more and no 123 fewer), and the value in each position must match the specified type for 124 that position. 125 126 For example: an object type of `object({ name=string, age=number })` would match 127 a value like the following: 128 129 ```hcl 130 { 131 name = "John" 132 age = 52 133 } 134 ``` 135 136 Also, an object type of `object({ id=string, cidr_block=string })` would match 137 the object produced by a reference to an `aws_vpc` resource, like 138 `aws_vpc.example_vpc`; although the resource has additional attributes, they 139 would be discarded during type conversion. 140 141 Finally, a tuple type of `tuple([string, number, bool])` would match a value 142 like the following: 143 144 ```hcl 145 ["a", 15, true] 146 ``` 147 148 ### Complex Type Literals 149 150 The Terraform language has literal expressions for creating tuple and object 151 values, which are described in 152 [Expressions: Literal Expressions](./expressions.html#literal-expressions) as 153 "list/tuple" literals and "map/object" literals, respectively. 154 155 Terraform does _not_ provide any way to directly represent lists, maps, or sets. 156 However, due to the automatic conversion of complex types (described below), the 157 difference between similar complex types is almost never relevant to a normal 158 user, and most of the Terraform documentation conflates lists with tuples and 159 maps with objects. The distinctions are only useful when restricting input 160 values for a module or resource. 161 162 ### Conversion of Complex Types 163 164 Similar kinds of complex types (list/tuple/set and map/object) can usually be 165 used interchangeably within the Terraform language, and most of Terraform's 166 documentation glosses over the differences between the kinds of complex type. 167 This is due to two conversion behaviors: 168 169 * Whenever possible, Terraform converts values between similar kinds of complex 170 types if the provided value is not the exact type requested. "Similar kinds" 171 is defined as follows: 172 * Objects and maps are similar. 173 * A map (or a larger object) can be converted to an object if it has 174 _at least_ the keys required by the object schema. Any additional 175 attributes are discarded during conversion, which means map -> object 176 -> map conversions can be lossy. 177 * Tuples and lists are similar. 178 * A list can only be converted to a tuple if it has _exactly_ the 179 required number of elements. 180 * Sets are _almost_ similar to both tuples and lists: 181 * When a list or tuple is converted to a set, duplicate values are 182 discarded and the ordering of elements is lost. 183 * When a `set` is converted to a list or tuple, the elements will be 184 in an arbitrary order. If the set's elements were strings, they will 185 be in lexicographical order; sets of other element types do not 186 guarantee any particular order of elements. 187 * Whenever possible, Terraform converts _element values_ within a complex type, 188 either by converting complex-typed elements recursively or as described above 189 in [Conversion of Primitive Types](#conversion-of-primitive-types). 190 191 For example: if a module argument requires a value of type `list(string)` and a 192 user provides the tuple `["a", 15, true]`, Terraform will internally transform 193 the value to `["a", "15", "true"]` by converting the elements to the required 194 `string` element type. Later, if the module uses those elements to set different 195 resource arguments that require a string, a number, and a bool (respectively), 196 Terraform will automatically convert the second and third strings back to the 197 required types at that time, since they contain valid representations of a 198 number and a bool. 199 200 On the other hand, automatic conversion will fail if the provided value 201 (including any of its element values) is incompatible with the required type. If 202 an argument requires a type of `map(string)` and a user provides the object 203 `{name = ["Kristy", "Claudia", "Mary Anne", "Stacey"], age = 12}`, Terraform 204 will raise a type mismatch error, since a tuple cannot be converted to a string. 205 206 ## Dynamic Types: The "any" Constraint 207 208 The keyword `any` is a special construct that serves as a placeholder for a 209 type yet to be decided. `any` is not _itself_ a type: when interpreting a 210 value against a type constraint containing `any`, Terraform will attempt to 211 find a single actual type that could replace the `any` keyword to produce 212 a valid result. 213 214 For example, given the type constraint `list(any)`, Terraform will examine 215 the given value and try to choose a replacement for the `any` that would 216 make the result valid. 217 218 If the given value were `["a", "b", "c"]` -- whose physical type is 219 `tuple([string, string, string])`, Terraform analyzes this as follows: 220 221 * Tuple types and list types are _similar_ per the previous section, so the 222 tuple-to-list conversion rule applies. 223 * All of the elements in the tuple are strings, so the type constraint 224 `string` would be valid for all of the list elements. 225 * Therefore in this case the `any` argument is replaced with `string`, 226 and the final concrete value type is `list(string)`. 227 228 All of the elements of a collection must have the same type, so conversion 229 to `list(any)` requires that all of the given elements must be convertible 230 to a common type. This implies some other behaviors that result from the 231 conversion rules described in earlier sections. 232 233 * If the given value were instead `["a", 1, "b"]` then Terraform would still 234 select `list(string)`, because of the primitive type conversion rules, and 235 the resulting value would be `["a", "1", "b"]` due to the string conversion 236 implied by that type constraint. 237 * If the given value were instead `["a", [], "b"]` then the value cannot 238 conform to the type constraint: there is no single type that both a string 239 and an empty tuple can convert to. Terraform would reject this value, 240 complaining that all elements must have the same type. 241 242 Although the above examples use `list(any)`, a similar principle applies to 243 `map(any)` and `set(any)`. 244 245 If you wish to apply absolutely no constraint to the given value, the `any` 246 keyword can be used in isolation: 247 248 ```hcl 249 variable "no_type_constraint" { 250 type = any 251 } 252 ``` 253 254 In this case, Terraform will replace `any` with the exact type of the given 255 value and thus perform no type conversion whatsoever.