github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/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 - [`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](/docs/language/expressions/types.html) 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](/docs/language/expressions/types.html). 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](/docs/language/functions/can.html) 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](/docs/language/state/index.html), 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_](/docs/language/state/sensitive-data.html). 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](/docs/extend/best-practices/sensitive-state.html#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](/docs/language/expressions/references.html#sensitive-resource-attributes). 278 279 If you use a sensitive value from as part of an 280 [output value](/docs/language/values/outputs.html) 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 Module 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 338 ## Using Input Variable Values 339 340 Within the module that declared a variable, its value can be accessed from 341 within [expressions](/docs/language/expressions/index.html) as `var.<NAME>`, 342 where `<NAME>` matches the label given in the declaration block: 343 344 -> **Note:** Input variables are _created_ by a `variable` block, but you 345 _reference_ them as attributes on an object named `var`. 346 347 ```hcl 348 resource "aws_instance" "example" { 349 instance_type = "t2.micro" 350 ami = var.image_id 351 } 352 ``` 353 354 The value assigned to a variable can only be accessed in expressions within 355 the module where it was declared. 356 357 ## Assigning Values to Root Module Variables 358 359 When variables are declared in the root module of your configuration, they 360 can be set in a number of ways: 361 362 * [In a Terraform Cloud workspace](/docs/cloud/workspaces/variables.html). 363 * Individually, with the `-var` command line option. 364 * In variable definitions (`.tfvars`) files, either specified on the command line 365 or automatically loaded. 366 * As environment variables. 367 368 The following sections describe these options in more detail. This section does 369 not apply to _child_ modules, where values for input variables are instead 370 assigned in the configuration of their parent module, as described in 371 [_Modules_](/docs/language/modules/index.html). 372 373 ### Variables on the Command Line 374 375 To specify individual variables on the command line, use the `-var` option 376 when running the `terraform plan` and `terraform apply` commands: 377 378 ``` 379 terraform apply -var="image_id=ami-abc123" 380 terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro" 381 terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}' 382 ``` 383 384 The above examples show appropriate syntax for Unix-style shells, such as on 385 Linux or macOS. For more information on shell quoting, including additional 386 examples for Windows Command Prompt, see 387 [Input Variables on the Command Line](/docs/cli/commands/plan.html#input-variables-on-the-command-line). 388 389 You can use the `-var` option multiple times in a single command to set several 390 different variables. 391 392 <a id="variable-files"></a> 393 394 ### Variable Definitions (`.tfvars`) Files 395 396 To set lots of variables, it is more convenient to specify their values in 397 a _variable definitions file_ (with a filename ending in either `.tfvars` 398 or `.tfvars.json`) and then specify that file on the command line with 399 `-var-file`: 400 401 ``` 402 terraform apply -var-file="testing.tfvars" 403 ``` 404 405 -> **Note:** This is how Terraform Cloud passes 406 [workspace variables](/docs/cloud/workspaces/variables.html) to Terraform. 407 408 A variable definitions file uses the same basic syntax as Terraform language 409 files, but consists only of variable name assignments: 410 411 ```hcl 412 image_id = "ami-abc123" 413 availability_zone_names = [ 414 "us-east-1a", 415 "us-west-1c", 416 ] 417 ``` 418 419 Terraform also automatically loads a number of variable definitions files 420 if they are present: 421 422 * Files named exactly `terraform.tfvars` or `terraform.tfvars.json`. 423 * Any files with names ending in `.auto.tfvars` or `.auto.tfvars.json`. 424 425 Files whose names end with `.json` are parsed instead as JSON objects, with 426 the root object properties corresponding to variable names: 427 428 ```json 429 { 430 "image_id": "ami-abc123", 431 "availability_zone_names": ["us-west-1a", "us-west-1c"] 432 } 433 ``` 434 435 ### Environment Variables 436 437 As a fallback for the other ways of defining variables, Terraform searches 438 the environment of its own process for environment variables named `TF_VAR_` 439 followed by the name of a declared variable. 440 441 This can be useful when running Terraform in automation, or when running a 442 sequence of Terraform commands in succession with the same variables. 443 For example, at a `bash` prompt on a Unix system: 444 445 ``` 446 $ export TF_VAR_image_id=ami-abc123 447 $ terraform plan 448 ... 449 ``` 450 451 On operating systems where environment variable names are case-sensitive, 452 Terraform matches the variable name exactly as given in configuration, and 453 so the required environment variable name will usually have a mix of upper 454 and lower case letters as in the above example. 455 456 ### Complex-typed Values 457 458 When variable values are provided in a variable definitions file, you can use 459 Terraform's usual syntax for 460 [literal expressions](/docs/language/expressions/types.html#literal-expressions) 461 to assign complex-typed values, like lists and maps. 462 463 Some special rules apply to the `-var` command line option and to environment 464 variables. For convenience, Terraform defaults to interpreting `-var` and 465 environment variable values as literal strings, which need only shell quoting, 466 and no special quoting for Terraform. For example, in a Unix-style shell: 467 468 ``` 469 $ export TF_VAR_image_id='ami-abc123' 470 ``` 471 472 However, if a root module variable uses a [type constraint](#type-constraints) 473 to require a complex value (list, set, map, object, or tuple), Terraform will 474 instead attempt to parse its value using the same syntax used within variable 475 definitions files, which requires careful attention to the string escaping rules 476 in your shell: 477 478 ``` 479 $ export TF_VAR_availability_zone_names='["us-west-1b","us-west-1d"]' 480 ``` 481 482 For readability, and to avoid the need to worry about shell escaping, we 483 recommend always setting complex variable values via variable definitions files. 484 For more information on quoting and escaping for `-var` arguments, 485 see 486 [Input Variables on the Command Line](/docs/cli/commands/plan.html#input-variables-on-the-command-line). 487 488 ### Values for Undeclared Variables 489 490 If you have defined a variable value, but not its corresponding `variable {}` 491 definition, you may get an error or warning depending on how you have provided 492 that value. 493 494 If you provide values for undeclared variables defined as [environment variables](#environment-variables) 495 you will not get an error or warning. This is because environment variables may 496 be declared but not used in all configurations that might be run. 497 498 If you provide values for undeclared variables defined [in a file](#variable-definitions-tfvars-files) 499 you will get a warning. This is to help in cases where you have provided a variable 500 value _meant_ for a variable declaration, but perhaps there is a mistake in the 501 value definition. For example, the following configuration: 502 503 ```terraform 504 variable "moose" { 505 type = string 506 } 507 ``` 508 509 And the following `.tfvars` file: 510 511 ```hcl 512 mosse = "Moose" 513 ``` 514 515 Will cause Terraform to warn you that there is no variable declared `"mosse"`, which can help 516 you spot this mistake. 517 518 If you use `.tfvars` files across multiple configurations and expect to continue to see this warning, 519 you can use the [`-compact-warnings`](https://www.terraform.io/docs/cli/commands/plan.html#compact-warnings) 520 option to simplify your output. 521 522 If you provide values for undeclared variables on the [command line](#variables-on-the-command-line), 523 Terraform will error. To avoid this error, either declare a variable block for the value, or remove 524 the variable value from your Terraform call. 525 526 ### Variable Definition Precedence 527 528 The above mechanisms for setting variables can be used together in any 529 combination. If the same variable is assigned multiple values, Terraform uses 530 the _last_ value it finds, overriding any previous values. Note that the same 531 variable cannot be assigned multiple values within a single source. 532 533 Terraform loads variables in the following order, with later sources taking 534 precedence over earlier ones: 535 536 * Environment variables 537 * The `terraform.tfvars` file, if present. 538 * The `terraform.tfvars.json` file, if present. 539 * Any `*.auto.tfvars` or `*.auto.tfvars.json` files, processed in lexical order 540 of their filenames. 541 * Any `-var` and `-var-file` options on the command line, in the order they 542 are provided. (This includes variables set by a Terraform Cloud 543 workspace.) 544 545 ~> **Important:** In Terraform 0.12 and later, variables with map and object 546 values behave the same way as other variables: the last value found overrides 547 the previous values. This is a change from previous versions of Terraform, which 548 would _merge_ map values instead of overriding them.