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.