--- layout: "docs" page_title: "Configuring Input Variables" sidebar_current: "docs-config-variables" description: |- Input variables are parameters for Terraform modules. This page covers configuration syntax for variables. --- # Input Variables Input variables serve as parameters for a Terraform module, allowing aspects of the a module to be customized without altering the module's own source code, and allowing modules to be shared between different configurations. When you declare variables in the root module of your configuration, you can set their values using CLI arguments and environment variables. When you declare them in [_child_ modules](/docs/configuration/modules.html), you can use the to pass values from parent to child. Input variable usage is introduced in the Getting Started guide section [_Input Variables_](/intro/getting-started/variables.html). ## Declaring an Input Variable Each input variable accepted by a module must be declared using a `variable` block: ```hcl variable "image_id" { type = string } variable "availability_zone_names" { type = list(string) default = ["us-west-1a"] } ``` For brevity, input variables are often referred to as just "variables" for short, where it is clear from context what sort of variable is being discussed. The label after the `variable` keyword is a name for the variable, which must be unique between all variables in the same module. This name is used to assign a value to the variable from outside and to reference the variable's value from within the module. The name of a variable can be any valid identifier. However, due to the interpretation of [module configuration blocks](/docs/configuration/modules.html), the names `source`, `version`, `providers`, `count`, `for_each`, and `lifecycle` are reserved for Terraform's own use and may not be declared as variable names. The variable declaration may optionally include a `type` argument, which describes what value types are accepted for the variable, as described in the following section. The variable declaration may also include a `default` argument. If present, the variable is considered to be _optional_ and the default value will be used if no overridden value is set when calling the module. The `default` argument requires a literal value and cannot reference other objects in the configuration. ## Using Input Variable Values Within the module that declared a variable, its value can be accessed from within [expressions](/docs/configuration/expressions.html) using an expression like `var.image_id`, where the name after the period corresponds to the label given in the declaration block: ```hcl resource "aws_instance" "example" { instance_type = "t2.micro" ami = var.image_id } ``` The value assigned to a variable can be accessed only from expressions within the module where it was declared. ## Type Constraints The `type` argument in a `variable` block allows you to restrict the type of value that will be accepted as the value for a variable. If no type constraint is set then a value of any type is accepted. While type constraints are optional, we recommend specifying them because it serves as helpful additional documentation for users of the module and it allows Terraform to return a helpful error message if the wrong type is used. Type constraints are created from a mixture of type keywords and type construction functions. The supported type keywords are: * `string` * `number` * `bool` The type construction functions allow you to specify complex types such as collections: * `list()` * `set()` * `map()` * `object({attr_name = , ... })` * `tuple([, ...])` The keyword `any` may be used to indicate that any type is acceptable. For more information on the meaning and behavior of these different types, see [the _Expressions_ section](/docs/configuration/expressions.html). If both the `type` and `default` arguments are specified, the given default valuable must be convertible to the specified type. ## Input Variable Documentation Because the input variables of a module are part of the user interface of the module, you may specify a short description of the purpose of each variable using the optional `description` argument: ```hcl variable "image_id" { type = string description = "The id of the machine image (AMI) to use for the server." } ``` The description for a variable should be a concise description of the purpose of the variable and what kind of value is expected. This description string may be included in documentation about the module, and so it should be written from the perspective of the user of the module rather than its maintainer. For commentary for module maintainers, use comments. ## Assigning Values to Root Module Variables When variables are declared in the root module of your configuration, they can be set in a number of ways: * Individual assignments made on the command line. * Variable definitions files, either specified on the command line or automatically loaded. * Environment variables. The following sections describe these options in more detail. This section does not apply to _child_ modules, where values for input variables are instead assigned in the configuration of their parent module, as described in [_Modules_](/docs/configuration/modules.html). ### Variables on the Command Line To specify individual modules on the command line, use the `-var` argument that is accepted by the `terraform plan` and `terraform apply` commands: ``` terraform apply -var="image_id=ami-abc123" ``` ### Variable Definitions Files To set lots of variables, it is more convenient to specify their values in a _variable definitions file_, with a filename ending in either `.tfvars` or `.tfvars.json`, and then specify that filename on the command line: ``` terraform apply -var-file="testing.tfvars" ``` A variable definitions file uses the same basic syntax as Terraform language files, but consists only of variable name assignments: ```hcl image_id = "ami-abc123" availability_zone_names = [ "us-east-1a", "us-west-1c", ] ``` Terraform also automatically loads a number of variable definitions files automatically if they are present: * Files named exactly `terraform.tfvars` or `terraform.tfvars.json`. * Any files with names ending in either `.auto.tfvars` or `.auto.tfvars.json`. Files whose names end with `.json` are parsed instead as JSON objects, with the root object properties corresponding to variable names: ```json { "image_id": "ami-abc123", "availability_zone_names": ["us-west-1a", "us-west-1c"] } ``` ### Environment Variables As a fallback for the other ways of defining variables, Terraform searches the environment of its own process for environment variables named `TF_VAR_` followed by the name of a declared variable. This can be useful when running Terraform in automation, or when running a sequence of Terraform commands in succession with the same variables. For example, at a `bash` prompt on a Unix system: ``` $ export TF_VAR_image_id=ami-abc123 $ terraform plan ... ``` On operating systems where environment variable names are case-sensitive, Terraform matches the variable name exactly as given in configuration, and so the required environment variable name will usually have a mix of upper and lower case letters as in the above example. ### Complex-typed Values When variable values are provided in a variable definitions file, the usual syntax can be used to assign complex-typed values, like lists and maps. Some special rules apply to the `-var` command line option and to environment variables: to allow string values to be set conveniently, by default values assigned in these ways are interpreted as literal strings, and thus do not need to be themselves quoted: ``` $ export TF_VAR_image_id=ami-abc123 ``` However, if a variable in the root module is declared as being of a complex type (list, set, map, object, or tuple), Terraform will instead attempt to parse it using the same syntax used within variable definitions files, which requires cafeful attention to the string escaping rules in your shell: ``` $ export TF_VAR_availability_zone_names='["us-west-1b","us-west-1d"]' ``` For readability, and to avoid the need to worry about shell escaping, we recommend always setting complex variable values via varable definitions files. ### Variable Definition Precedence The above mechanisms for defining variable values can be used together in any combination. If the same variable is assigned multiple values, the processing order is as follows, with the later items in this list taking precedence over the earlier: * Environment Variables * The `terraform.tfvars` file, if present. * The `terraform.tfvars.json` file, if present. * Any `-var` and `-var-file` arguments on the command line, in the order they are provided.