github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/website/docs/language/functions/defaults.html.md (about) 1 --- 2 layout: "language" 3 page_title: "defaults - Functions - Configuration Language" 4 sidebar_current: "docs-funcs-conversion-defaults" 5 description: |- 6 The defaults function can fill in default values in place of null values. 7 --- 8 9 # `defaults` Function 10 11 -> **Note:** This function is available only in Terraform 0.15 and later. 12 13 ~> **Experimental:** This function is part of 14 [the optional attributes experiment](/docs/language/expressions/type-constraints.html#experimental-optional-object-type-attributes) 15 and is only available in modules where the `module_variable_optional_attrs` 16 experiment is explicitly enabled. 17 18 The `defaults` function is a specialized function intended for use with 19 input variables whose type constraints are object types or collections of 20 object types that include optional attributes. 21 22 When you define an attribute as optional and the caller doesn't provide an 23 explicit value for it, Terraform will set the attribute to `null` to represent 24 that it was omitted. If you want to use a placeholder value other than `null` 25 when an attribute isn't set, you can use the `defaults` function to concisely 26 assign default values only where an attribute value was set to `null`. 27 28 ``` 29 defaults(input_value, defaults) 30 ``` 31 32 The `defaults` function expects that the `input_value` argument will be the 33 value of an input variable with an exact [type constraint](/docs/language/expressions/types.html) 34 (not containing `any`). The function will then visit every attribute in 35 the data structure, including attributes of nested objects, and apply the 36 default values given in the defaults object. 37 38 The interpretation of attributes in the `defaults` argument depends on what 39 type an attribute has in the `input_value`: 40 41 * **Primitive types** (`string`, `number`, `bool`): if a default value is given 42 then it will be used only if the `input_value`'s attribute of the same 43 name has the value `null`. The default value's type must match the input 44 value's type. 45 * **Structural types** (`object` and `tuple` types): Terraform will recursively 46 visit all of the attributes or elements of the nested value and repeat the 47 same defaults-merging logic one level deeper. The default value's type must 48 be of the same kind as the input value's type, and a default value for an 49 object type must only contain attribute names that appear in the input 50 value's type. 51 * **Collection types** (`list`, `map`, and `set` types): Terraform will visit 52 each of the collection elements in turn and apply defaults to them. In this 53 case the default value is only a single value to be applied to _all_ elements 54 of the collection, so it must have a type compatible with the collection's 55 element type rather than with the collection type itself. 56 57 The above rules may be easier to follow with an example. Consider the following 58 Terraform configuration: 59 60 ```hcl 61 terraform { 62 # Optional attributes and the defaults function are 63 # both experimental, so we must opt in to the experiment. 64 experiments = [module_variable_optional_attrs] 65 } 66 67 variable "storage" { 68 type = object({ 69 name = string 70 enabled = optional(bool) 71 website = object({ 72 index_document = optional(string) 73 error_document = optional(string) 74 }) 75 documents = map( 76 object({ 77 source_file = string 78 content_type = optional(string) 79 }) 80 ) 81 }) 82 } 83 84 locals { 85 storage = defaults(var.storage, { 86 # If "enabled" isn't set then it will default 87 # to true. 88 enabled = true 89 90 # The "website" attribute is required, but 91 # it's here to provide defaults for the 92 # optional attributes inside. 93 website = { 94 index_document = "index.html" 95 error_document = "error.html" 96 } 97 98 # The "documents" attribute has a map type, 99 # so the default value represents defaults 100 # to be applied to all of the elements in 101 # the map, not for the map itself. Therefore 102 # it's a single object matching the map 103 # element type, not a map itself. 104 documents = { 105 # If _any_ of the map elements omit 106 # content_type then this default will be 107 # used instead. 108 content_type = "application/octet-stream" 109 } 110 }) 111 } 112 113 output "storage" { 114 value = local.storage 115 } 116 ``` 117 118 To test this out, we can create a file `terraform.tfvars` to provide an example 119 value for `var.storage`: 120 121 ```hcl 122 storage = { 123 name = "example" 124 125 website = { 126 error_document = "error.txt" 127 } 128 documents = { 129 "index.html" = { 130 source_file = "index.html.tmpl" 131 content_type = "text/html" 132 } 133 "error.txt" = { 134 source_file = "error.txt.tmpl" 135 content_type = "text/plain" 136 } 137 "terraform.exe" = { 138 source_file = "terraform.exe" 139 } 140 } 141 } 142 ``` 143 144 The above value conforms to the variable's type constraint because it only 145 omits attributes that are declared as optional. Terraform will automatically 146 populate those attributes with the value `null` before evaluating anything 147 else, and then the `defaults` function in `local.storage` will substitute 148 default values for each of them. 149 150 The result of this `defaults` call would therefore be the following object: 151 152 ``` 153 storage = { 154 "documents" = tomap({ 155 "error.txt" = { 156 "content_type" = "text/plain" 157 "source_file" = "error.txt.tmpl" 158 } 159 "index.html" = { 160 "content_type" = "text/html" 161 "source_file" = "index.html.tmpl" 162 } 163 "terraform.exe" = { 164 "content_type" = "application/octet-stream" 165 "source_file" = "terraform.exe" 166 } 167 }) 168 "enabled" = true 169 "name" = "example" 170 "website" = { 171 "error_document" = "error.txt" 172 "index_document" = "index.html" 173 } 174 } 175 ``` 176 177 Notice that `enabled` and `website.index_document` were both populated directly 178 from the defaults. Notice also that the `"terraform.exe"` element of 179 `documents` had its `content_type` attribute populated from the `documents` 180 default, but the default value didn't need to predict that there would be an 181 element key `"terraform.exe"` because the default values apply equally to 182 all elements of the map where the optional attributes are `null`. 183 184 ## Using `defaults` elsewhere 185 186 The design of the `defaults` function depends on input values having 187 well-specified type constraints, so it can reliably recognize the difference 188 between similar types: maps vs. objects, lists vs. tuples. The type constraint 189 causes Terraform to convert the caller's value to conform to the constraint 190 and thus `defaults` can rely on the input to conform. 191 192 Elsewhere in the Terraform language it's typical to be less precise about 193 types, for example using the object construction syntax `{ ... }` to construct 194 values that will be used as if they are maps. Because `defaults` uses the 195 type information of `input_value`, an `input_value` that _doesn't_ originate 196 in an input variable will tend not to have an appropriate value type and will 197 thus not be interpreted as expected by `defaults`. 198 199 We recommend using `defaults` only with fully-constrained input variable values 200 in the first argument, so you can use the variable's type constraint to 201 explicitly distinguish between collection and structural types.