terraform/website/docs/configuration/variables.html.md

253 lines
8.7 KiB
Markdown

---
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(<type>)`
* `set(<type>)`
* `map(<type>)`
* `object({attr_name = <type>, ... })`
* `tuple([<type>, ...])`
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.