github.com/hugorut/terraform@v1.1.3/website/docs/language/values/variables.mdx (about)

     1  ---
     2  page_title: Input Variables - Configuration Language
     3  description: >-
     4    Input variables allow you to customize modules without altering their source
     5    code. Learn how to declare, define, and reference variables in configurations.
     6  ---
     7  
     8  # Input Variables
     9  
    10  > **Hands-on:** Try the [Customize Terraform Configuration with Variables](https://learn.hashicorp.com/tutorials/terraform/variables?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
    11  
    12  Input variables let you customize aspects of Terraform modules without altering
    13  the module's own source code. This allows you to share modules across different
    14  Terraform configurations, making your module composable and reusable.
    15  
    16  When you declare variables in the root module of your configuration, you can
    17  set their values using CLI options and environment variables.
    18  When you declare them in [child modules](/language/modules),
    19  the calling module should pass values in the `module` block.
    20  
    21  If you're familiar with traditional programming languages, it can be useful to
    22  compare Terraform modules to function definitions:
    23  
    24  * Input variables are like function arguments.
    25  * [Output values](/language/values/outputs) are like function return values.
    26  * [Local values](/language/values/locals) are like a function's temporary local variables.
    27  
    28  -> **Note:** For brevity, input variables are often referred to as just
    29  "variables" or "Terraform variables" when it is clear from context what sort of
    30  variable is being discussed. Other kinds of variables in Terraform include
    31  _environment variables_ (set by the shell where Terraform runs) and _expression
    32  variables_ (used to indirectly represent a value in an
    33  [expression](/language/expressions)).
    34  
    35  ## Declaring an Input Variable
    36  
    37  Each input variable accepted by a module must be declared using a `variable`
    38  block:
    39  
    40  ```hcl
    41  variable "image_id" {
    42    type = string
    43  }
    44  
    45  variable "availability_zone_names" {
    46    type    = list(string)
    47    default = ["us-west-1a"]
    48  }
    49  
    50  variable "docker_ports" {
    51    type = list(object({
    52      internal = number
    53      external = number
    54      protocol = string
    55    }))
    56    default = [
    57      {
    58        internal = 8300
    59        external = 8300
    60        protocol = "tcp"
    61      }
    62    ]
    63  }
    64  ```
    65  
    66  The label after the `variable` keyword is a name for the variable, which must
    67  be unique among all variables in the same module. This name is used to
    68  assign a value to the variable from outside and to reference the variable's
    69  value from within the module.
    70  
    71  The name of a variable can be any valid [identifier](/language/syntax/configuration#identifiers)
    72  _except_ the following: `source`, `version`, `providers`, `count`, `for_each`, `lifecycle`, `depends_on`, `locals`.
    73  
    74  These names are reserved for meta-arguments in
    75  [module configuration blocks](/language/modules/syntax), and cannot be
    76  declared as variable names.
    77  
    78  ## Arguments
    79  
    80  Terraform CLI defines the following optional arguments for variable declarations:
    81  
    82  * [`default`][inpage-default] - A default value which then makes the variable optional.
    83  * [`type`][inpage-type] - This argument specifies what value types are accepted for the variable.
    84  * [`description`][inpage-description] - This specifies the input variable's documentation.
    85  * [`validation`][inpage-validation] - A block to define validation rules, usually in addition to type constraints.
    86  * [`sensitive`][inpage-sensitive] - Limits Terraform UI output when the variable is used in configuration.
    87  * [`nullable`][inpage-nullable] - Specify if the variable can be `null` within the module.
    88  
    89  ### Default values
    90  
    91  [inpage-default]: #default-values
    92  
    93  The variable declaration can also include a `default` argument. If present,
    94  the variable is considered to be _optional_ and the default value will be used
    95  if no value is set when calling the module or running Terraform. The `default`
    96  argument requires a literal value and cannot reference other objects in the
    97  configuration.
    98  
    99  ### Type Constraints
   100  
   101  [inpage-type]: #type-constraints
   102  
   103  The `type` argument in a `variable` block allows you to restrict the
   104  [type of value](/language/expressions/types) that will be accepted as
   105  the value for a variable. If no type constraint is set then a value of any type
   106  is accepted.
   107  
   108  While type constraints are optional, we recommend specifying them; they
   109  can serve as helpful reminders for users of the module, and they
   110  allow Terraform to return a helpful error message if the wrong type is used.
   111  
   112  Type constraints are created from a mixture of type keywords and type
   113  constructors. The supported type keywords are:
   114  
   115  * `string`
   116  * `number`
   117  * `bool`
   118  
   119  The type constructors allow you to specify complex types such as
   120  collections:
   121  
   122  * `list(<TYPE>)`
   123  * `set(<TYPE>)`
   124  * `map(<TYPE>)`
   125  * `object({<ATTR NAME> = <TYPE>, ... })`
   126  * `tuple([<TYPE>, ...])`
   127  
   128  The keyword `any` may be used to indicate that any type is acceptable. For
   129  more information on the meaning and behavior of these different types, as well
   130  as detailed information about automatic conversion of complex types, see
   131  [Type Constraints](/language/expressions/types).
   132  
   133  If both the `type` and `default` arguments are specified, the given default
   134  value must be convertible to the specified type.
   135  
   136  ### Input Variable Documentation
   137  
   138  [inpage-description]: #input-variable-documentation
   139  
   140  Because the input variables of a module are part of its user interface, you can
   141  briefly describe the purpose of each variable using the optional
   142  `description` argument:
   143  
   144  ```hcl
   145  variable "image_id" {
   146    type        = string
   147    description = "The id of the machine image (AMI) to use for the server."
   148  }
   149  ```
   150  
   151  The description should concisely explain the purpose
   152  of the variable and what kind of value is expected. This description string
   153  might be included in documentation about the module, and so it should be written
   154  from the perspective of the user of the module rather than its maintainer. For
   155  commentary for module maintainers, use comments.
   156  
   157  ### Custom Validation Rules
   158  
   159  [inpage-validation]: #custom-validation-rules
   160  
   161  -> This feature was introduced in Terraform CLI v0.13.0.
   162  
   163  In addition to Type Constraints as described above, a module author can specify
   164  arbitrary custom validation rules for a particular variable using a `validation`
   165  block nested within the corresponding `variable` block:
   166  
   167  ```hcl
   168  variable "image_id" {
   169    type        = string
   170    description = "The id of the machine image (AMI) to use for the server."
   171  
   172    validation {
   173      condition     = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
   174      error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
   175    }
   176  }
   177  ```
   178  
   179  The `condition` argument is an expression that must use the value of the
   180  variable to return `true` if the value is valid, or `false` if it is invalid.
   181  The expression can refer only to the variable that the condition applies to,
   182  and _must not_ produce errors.
   183  
   184  If the failure of an expression is the basis of the validation decision, use
   185  [the `can` function](/language/functions/can) to detect such errors. For example:
   186  
   187  ```hcl
   188  variable "image_id" {
   189    type        = string
   190    description = "The id of the machine image (AMI) to use for the server."
   191  
   192    validation {
   193      # regex(...) fails if it cannot find a match
   194      condition     = can(regex("^ami-", var.image_id))
   195      error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
   196    }
   197  }
   198  ```
   199  
   200  If `condition` evaluates to `false`, Terraform will produce an error message
   201  that includes the sentences given in `error_message`. The error message string
   202  should be at least one full sentence explaining the constraint that failed,
   203  using a sentence structure similar to the above examples.
   204  
   205  Multiple `validation` blocks can be declared in which case error messages
   206  will be returned for _all_ failed conditions.
   207  
   208  ### Suppressing Values in CLI Output
   209  
   210  [inpage-sensitive]: #suppressing-values-in-cli-output
   211  
   212  -> This feature was introduced in Terraform v0.14.0.
   213  
   214  > **Hands-on:** Try the [Protect Sensitive Input Variables](https://learn.hashicorp.com/tutorials/terraform/sensitive-variables?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
   215  
   216  Setting a variable as `sensitive` prevents Terraform from showing its value in
   217  the `plan` or `apply` output, when you use that variable elsewhere in your
   218  configuration.
   219  
   220  Terraform will still record sensitive values in the [state](/language/state),
   221  and so anyone who can access the state data will have access to the sensitive
   222  values in cleartext. For more information, see
   223  [_Sensitive Data in State_](/language/state/sensitive-data).
   224  
   225  Declare a variable as sensitive by setting the `sensitive` argument to `true`:
   226  
   227  ```
   228  variable "user_information" {
   229    type = object({
   230      name    = string
   231      address = string
   232    })
   233    sensitive = true
   234  }
   235  
   236  resource "some_resource" "a" {
   237    name    = var.user_information.name
   238    address = var.user_information.address
   239  }
   240  ```
   241  
   242  Any expressions whose result depends on the sensitive variable will be treated
   243  as sensitive themselves, and so in the above example the two arguments of
   244  `resource "some_resource" "a"` will also be hidden in the plan output:
   245  
   246  ```
   247  Terraform will perform the following actions:
   248  
   249    # some_resource.a will be created
   250    + resource "some_resource" "a" {
   251        + name    = (sensitive)
   252        + address = (sensitive)
   253      }
   254  
   255  Plan: 1 to add, 0 to change, 0 to destroy.
   256  ```
   257  
   258  In some cases where you use a sensitive variable inside a nested block, Terraform
   259  may treat the entire block as redacted. This happens for resource types where
   260  all of the blocks of a particular type are required to be unique, and so
   261  disclosing the content of one block might imply the content of a sibling block.
   262  
   263  ```
   264    # some_resource.a will be updated in-place
   265    ~ resource "some_resource" "a" {
   266        ~ nested_block {
   267            # At least one attribute in this block is (or was) sensitive,
   268            # so its contents will not be displayed.
   269          }
   270      }
   271  ```
   272  
   273  A provider can also
   274  [declare an attribute as sensitive](/plugin/sdkv2/best-practices/sensitive-state#using-the-sensitive-flag),
   275  which will cause Terraform to hide it from regular output regardless of how
   276  you assign it a value. For more information, see
   277  [Sensitive Resource Attributes](/language/expressions/references#sensitive-resource-attributes).
   278  
   279  If you use a sensitive value from as part of an
   280  [output value](/language/values/outputs) then Terraform will require
   281  you to also mark the output value itself as sensitive, to confirm that you
   282  intended to export it.
   283  
   284  #### Cases where Terraform may disclose a sensitive variable
   285  
   286  A `sensitive` variable is a configuration-centered concept, and values are sent to providers without any obfuscation. A provider error could disclose a value if that value is included in the error message. For example, a provider might return the following error even if "foo" is a sensitive value: `"Invalid value 'foo' for field"`
   287  
   288  If a resource attribute is used as, or part of, the provider-defined resource id, an `apply` will disclose the value. In the example below, the `prefix` attribute has been set to a sensitive variable, but then that value ("jae") is later disclosed as part of the resource id:
   289  
   290  ```
   291    # random_pet.animal will be created
   292    + resource "random_pet" "animal" {
   293        + id        = (known after apply)
   294        + length    = 2
   295        + prefix    = (sensitive)
   296        + separator = "-"
   297      }
   298  
   299  Plan: 1 to add, 0 to change, 0 to destroy.
   300  
   301  ...
   302  
   303  random_pet.animal: Creating...
   304  random_pet.animal: Creation complete after 0s [id=jae-known-mongoose]
   305  ```
   306  
   307  ### Disallowing Null Input Values
   308  
   309  [inpage-nullable]: #disallowing-null-input-values
   310  
   311  -> This feature is available in Terraform v1.1.0 and later.
   312  
   313  The `nullable` argument in a variable block controls whether the module caller
   314  may assign the value `null` to the variable.
   315  
   316  ```
   317  variable "example" {
   318    type     = string
   319    nullable = false 
   320  }
   321  ```
   322  
   323  The default value for `nullable` is `true`. When `nullable` is `true`, `null`
   324  is a valid value for the variable, and the module configuration must always
   325  account for the possibility of the variable value being `null`. Passing a
   326  `null` value as a module input argument will override any `default` value.
   327  
   328  Setting `nullable` to `false` ensures that the variable value will never be
   329  `null` within the module. If `nullable` is `false` and the variable has a
   330  `default` value, then Terraform uses the default when a module input argument is `null`.
   331  
   332  The `nullable` argument only controls where the direct value of the variable may be `null`.
   333  For variables of collection or structural types, such as lists or objects,
   334  the caller may still use `null` in nested elements or attributes, as long as
   335  the collection or structure itself is not null.
   336  
   337  ## Using Input Variable Values
   338  
   339  Within the module that declared a variable, its value can be accessed from
   340  within [expressions](/language/expressions) as `var.<NAME>`,
   341  where `<NAME>` matches the label given in the declaration block:
   342  
   343  -> **Note:** Input variables are _created_ by a `variable` block, but you
   344  _reference_ them as attributes on an object named `var`.
   345  
   346  ```hcl
   347  resource "aws_instance" "example" {
   348    instance_type = "t2.micro"
   349    ami           = var.image_id
   350  }
   351  ```
   352  
   353  The value assigned to a variable can only be accessed in expressions within
   354  the module where it was declared.
   355  
   356  ## Assigning Values to Root Module Variables
   357  
   358  When variables are declared in the root module of your configuration, they
   359  can be set in a number of ways:
   360  
   361  * [In a Terraform Cloud workspace](/cloud-docs/workspaces/variables).
   362  * Individually, with the `-var` command line option.
   363  * In variable definitions (`.tfvars`) files, either specified on the command line
   364    or automatically loaded.
   365  * As environment variables.
   366  
   367  The following sections describe these options in more detail. This section does
   368  not apply to _child_ modules, where values for input variables are instead
   369  assigned in the configuration of their parent module, as described in
   370  [_Modules_](/language/modules).
   371  
   372  ### Variables on the Command Line
   373  
   374  To specify individual variables on the command line, use the `-var` option
   375  when running the `terraform plan` and `terraform apply` commands:
   376  
   377  ```
   378  terraform apply -var="image_id=ami-abc123"
   379  terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
   380  terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'
   381  ```
   382  
   383  The above examples show appropriate syntax for Unix-style shells, such as on
   384  Linux or macOS. For more information on shell quoting, including additional
   385  examples for Windows Command Prompt, see
   386  [Input Variables on the Command Line](/cli/commands/plan#input-variables-on-the-command-line).
   387  
   388  You can use the `-var` option multiple times in a single command to set several
   389  different variables.
   390  
   391  <a id="variable-files"></a>
   392  
   393  ### Variable Definitions (`.tfvars`) Files
   394  
   395  To set lots of variables, it is more convenient to specify their values in
   396  a _variable definitions file_ (with a filename ending in either `.tfvars`
   397  or `.tfvars.json`) and then specify that file on the command line with
   398  `-var-file`:
   399  
   400  ```
   401  terraform apply -var-file="testing.tfvars"
   402  ```
   403  
   404  -> **Note:** This is how Terraform Cloud passes
   405  [workspace variables](/cloud-docs/workspaces/variables) to Terraform.
   406  
   407  A variable definitions file uses the same basic syntax as Terraform language
   408  files, but consists only of variable name assignments:
   409  
   410  ```hcl
   411  image_id = "ami-abc123"
   412  availability_zone_names = [
   413    "us-east-1a",
   414    "us-west-1c",
   415  ]
   416  ```
   417  
   418  Terraform also automatically loads a number of variable definitions files
   419  if they are present:
   420  
   421  * Files named exactly `terraform.tfvars` or `terraform.tfvars.json`.
   422  * Any files with names ending in `.auto.tfvars` or `.auto.tfvars.json`.
   423  
   424  Files whose names end with `.json` are parsed instead as JSON objects, with
   425  the root object properties corresponding to variable names:
   426  
   427  ```json
   428  {
   429    "image_id": "ami-abc123",
   430    "availability_zone_names": ["us-west-1a", "us-west-1c"]
   431  }
   432  ```
   433  
   434  ### Environment Variables
   435  
   436  As a fallback for the other ways of defining variables, Terraform searches
   437  the environment of its own process for environment variables named `TF_VAR_`
   438  followed by the name of a declared variable.
   439  
   440  This can be useful when running Terraform in automation, or when running a
   441  sequence of Terraform commands in succession with the same variables.
   442  For example, at a `bash` prompt on a Unix system:
   443  
   444  ```
   445  $ export TF_VAR_image_id=ami-abc123
   446  $ terraform plan
   447  ...
   448  ```
   449  
   450  On operating systems where environment variable names are case-sensitive,
   451  Terraform matches the variable name exactly as given in configuration, and
   452  so the required environment variable name will usually have a mix of upper
   453  and lower case letters as in the above example.
   454  
   455  ### Complex-typed Values
   456  
   457  When variable values are provided in a variable definitions file, you can use
   458  Terraform's usual syntax for
   459  [literal expressions](/language/expressions/types#literal-expressions)
   460  to assign complex-typed values, like lists and maps.
   461  
   462  Some special rules apply to the `-var` command line option and to environment
   463  variables. For convenience, Terraform defaults to interpreting `-var` and
   464  environment variable values as literal strings, which need only shell quoting,
   465  and no special quoting for Terraform. For example, in a Unix-style shell:
   466  
   467  ```
   468  $ export TF_VAR_image_id='ami-abc123'
   469  ```
   470  
   471  However, if a root module variable uses a [type constraint](#type-constraints)
   472  to require a complex value (list, set, map, object, or tuple), Terraform will
   473  instead attempt to parse its value using the same syntax used within variable
   474  definitions files, which requires careful attention to the string escaping rules
   475  in your shell:
   476  
   477  ```
   478  $ export TF_VAR_availability_zone_names='["us-west-1b","us-west-1d"]'
   479  ```
   480  
   481  For readability, and to avoid the need to worry about shell escaping, we
   482  recommend always setting complex variable values via variable definitions files.
   483  For more information on quoting and escaping for `-var` arguments,
   484  see
   485  [Input Variables on the Command Line](/cli/commands/plan#input-variables-on-the-command-line).
   486  
   487  ### Values for Undeclared Variables
   488  
   489  If you have defined a variable value, but not its corresponding `variable {}`
   490  definition, you may get an error or warning depending on how you have provided
   491  that value.
   492  
   493  If you provide values for undeclared variables defined as [environment variables](#environment-variables)
   494  you will not get an error or warning. This is because environment variables may
   495  be declared but not used in all configurations that might be run.
   496  
   497  If you provide values for undeclared variables defined [in a file](#variable-definitions-tfvars-files)
   498  you will get a warning. This is to help in cases where you have provided a variable
   499  value _meant_ for a variable declaration, but perhaps there is a mistake in the
   500  value definition. For example, the following configuration:
   501  
   502  ```terraform
   503  variable "moose" {
   504    type = string
   505  }
   506  ```
   507  
   508  And the following `.tfvars` file:
   509  
   510  ```hcl
   511  moose = "Moose"
   512  ```
   513  
   514  Will cause Terraform to warn you that there is no variable declared `"mosse"`, which can help
   515  you spot this mistake.
   516  
   517  If you use `.tfvars` files across multiple configurations and expect to continue to see this warning,
   518  you can use the [`-compact-warnings`](/cli/commands/plan#compact-warnings)
   519  option to simplify your output.
   520  
   521  If you provide values for undeclared variables on the [command line](#variables-on-the-command-line),
   522  Terraform will error. To avoid this error, either declare a variable block for the value, or remove
   523  the variable value from your Terraform call.
   524  
   525  ### Variable Definition Precedence
   526  
   527  The above mechanisms for setting variables can be used together in any
   528  combination. If the same variable is assigned multiple values, Terraform uses
   529  the _last_ value it finds, overriding any previous values. Note that the same
   530  variable cannot be assigned multiple values within a single source.
   531  
   532  Terraform loads variables in the following order, with later sources taking
   533  precedence over earlier ones:
   534  
   535  * Environment variables
   536  * The `terraform.tfvars` file, if present.
   537  * The `terraform.tfvars.json` file, if present.
   538  * Any `*.auto.tfvars` or `*.auto.tfvars.json` files, processed in lexical order
   539    of their filenames.
   540  * Any `-var` and `-var-file` options on the command line, in the order they
   541    are provided. (This includes variables set by a Terraform Cloud
   542    workspace.)
   543  
   544  ~> **Important:** In Terraform 0.12 and later, variables with map and object
   545  values behave the same way as other variables: the last value found overrides
   546  the previous values. This is a change from previous versions of Terraform, which
   547  would _merge_ map values instead of overriding them.