github.com/jaredpalmer/terraform@v1.1.0-alpha20210908.0.20210911170307-88705c943a03/website/docs/language/values/variables.html.md (about)

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