Variable can be defined in a variable
block in #HashiCorp Configuration Language (HCL) for #HashiCorp Terraform in the file variables.tf
. A comprehensive definition for a variable
block should look like the following:
variable filename {
default: "Hello World"
type: string
description: "To say hello world to the outside world"
}
The default
field defined the default value for the variable filename
. This must adhere to the type that you have specified in the field type
. description
is generally used for documenting. All these arguments are optional, so we can actually define an empty variable block without triggering any warnings or errors.
The values of the variables can be assigned else where. You can put their values inside a file named terraform.tfvars
or terraform.tfvars.json
, or any file that has post-fix .auto.tfvars
or .auto.tfvars.json
. The following shows the syntax to define these files, which is similar to of the style of JSON file:
filename = "Hello World"
isComputer = true
total = 45
We can even define the value for the variables using environment variable or the command option -var
before running terraform apply
. If the environment variable is intended to refer to the variable defined in variables.tf
, they need to have a format TF_VAR_{variable name}
in order to be recognised by Terraform. In the case of -var
, you can simply define them in the style -var {variable name}={value}
. For every variable, one -var
should be used.
The precedence of defined values for the variables is like this: environment variables has the lowest precedence, next the terraform.tfvars
and its JSON counterpart, then auto.tfvars
and its JSON counterpart, and -var
and -var-file
has the highest precedence. Higher precedence of defined values will override the lower one.
If the variable
block doesn’t contain the default value of the variable and its value can’t be found in all the method mentioned above, then Terraform will prompt for the value.
To use or import variables into another file, we can utilise the prefix var
in the format form of var.{variable name}
. For example:
resource "local_file" "example" {
filename = var.filename
}
Note: There are some variables defined in the resources are read-only, meaning we can’t override or assign values to them.
We could convert the value from the Terraform Providers# using the output
block to output the variable onto the screen or be used by external program such as Ansible and shell scripts. It accepts only one parameter, that is the name for the to be defined variable. The mandatory argument for it is value
argument, which is used to refer to the value from the resource block. description
is a description for this output variable, but it is optional.
output "file_id" {
value = local_file.example.id
description = "This is an example usage of output block"
}
Output variables could be inspected using the command terraform output
.
Type
There are several types available to enforce type checking for a variable, including string
, number
, bool
, any
, list
, map
, set
, object
and tuple
. We can define it in the field type
within the variable
block.
list
can be treated as typical array, meaning you could access the elements inside the list
using the []
syntax with an index number starting at 0.
For list
, map
and set
, we can constrain the type of these collections by using the syntax ()
. The following code takes advantage of this to restrict the list
to only accept boolean type values:
variable a_list {
default = [true, false, true]
type = list(bool)
}
set
is almost identical to of list
, except that it doesn’t allow repeated values. A list
could be converted to set
with the function toset()
.
map
has a minor differing syntax to list
and set
. It accepts a key and a value where you can later retrieve it using []
with the key name. This is best shown as an example:
variable a_map {
default = [
"key1" = "This is the first value"
"key2" = "This is the second value"
]
type = map(string)
}
The type object
has a similar syntax to map
. We can assign multiple types of variable to an object
. This is shown as below:
variable an_object {
default = {
first-var = "Hello World"
second-var = 420
thrid-var = ["cat", "dog", "rat"]
}
type = object({
first-var = string
second-var = number
thrid-var = list(string)
})
}
As you can see, it uses a different bracket {}
to define an object. Note that the key name must be the same to the key name declared in the type
field.
tuple
can be defined to include a collection of variables coming from different types. It uses []
to define the type information of the variables.
variable a_tuple {
default = [true, "dolphin", 69]
type = tuple([bool, string, number])
}