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.