Terraform Variables
Terraform variables provide a flexible and dynamic approach to codify infrastructure. They offer a way to customize modules without altering the source code, making your modules reusable across different configurations. Variables can be declared in the root module, where they can be assigned values using CLI options and environment variables.
Declaring a Variable
A variable in Terraform is declared using a variable
block. It requires a unique label, which serves as the variable's name. The label is used to assign a value from outside the module and to reference the value within the module.
Here's an example showcasing different types of variable declarations:
variable "account_id" {}
variable "instance_id" {
type = string
}
variable "subnet_ids" {
type = list(string)
default = ["subnet-0a4b1f2c3d4e5f6g"]
}
variable "security_group_settings" {
type = list(object({
rule = number
port_range = number
protocol = string
}))
default = [
{
rule = 22
port_range = 22
protocol = "tcp"
}
]
}
Variable Arguments
Terraform CLI defines the following optional arguments for variable declarations:
default
: A default value which then makes the variable optional.type
: This argument specifies what value types are accepted for the variable.description
: This specifies the variable's documentation.validation
: A block to define validation rules, usually in addition to type constraints.sensitive
: Limits Terraform UI output when the variable is used in configuration.nullable
: Specify if the variable can be null within the module.
Default Values
A variable declaration can include a default
argument, making the variable optional. If no value is set when calling the module or running Terraform, the default value is used. The default
argument requires a literal value and cannot reference other configuration objects.
variable "instance_type" {
type = string
default = "t2.micro"
}
Type Constraints
The type
argument in a variable
block restricts the type of value that the variable can accept. If no type constraint is set, a value of any type is accepted. Type constraints are not mandatory, but are recommended to provide clarity for users and to enable helpful error messages from Terraform.
Type constraints are created from a mixture of type keywords and type constructors. The supported type keywords are:
string
number
bool
The type constructors 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. If both the type
and default
arguments are specified, the default value must be convertible to the specified type.
Variable Documentation
To provide clarity to users of the module, the description
argument can be used to explain the variable's purpose and expected value.
variable "image_id" {
type = string
description = "The id of the machine image (AMI) to use for the server."
}
Custom Validation Rules
A validation
block can be added within the variable
block to specify custom validation rules for a variable.
Example of a validation rule for checking instance ID syntax:
variable "instance_id" {
type = string
description = "The ID of the EC2 instance to manage."
validation {
condition = length(var.instance_id) > 4 && substr(var.instance_id, 0, 4) == "i-"
error_message = "The instance_id value must be a valid instance ID, starting with \"i-\"."
}
}
Suppressing Values in CLI Output
The sensitive
argument can be used to prevent Terraform from displaying a variable's value in the plan
or apply
output. This argument is useful when you want to hide potentially sensitive data from being displayed in the console.
variable "database_password" {
type = string
sensitive = true
}
Disallowing Null Input Values
The nullable
argument can be used to specify whether the variable can accept null
as its value. If nullable
is set to false
, the variable value can never be null
within the module. The default value for nullable
is true
.
variable "subnet_id" {
type = string
nullable = false
}
Using and Assigning Variable Values
Once declared, variable values can be accessed and manipulated in a variety of ways within your Terraform configuration.
Accessing Variable Values
In the module that declared a variable, you can use the var.<NAME>
syntax to access the variable value within expressions. <NAME>
should match the label provided in the declaration block. For example:
resource "aws_instance" "example" {
instance_type = "t2.micro"
ami = var.ami_id
}
This access is restricted to the module in which the variable is declared.
Assigning Values to Root Module Variables
For variables declared in the root module of your configuration, values can be set through various methods:
- Terraform Cloud workspace
- Command line option
-var
- Variable definitions files (
.tfvars
) - Environment variables
Variables on the Command Line
To specify individual variables on the command line, use the -var
option when running the terraform plan
and terraform apply
commands:
$ terraform apply -var="image_id=ami-abc123"
$ terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
$ terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'
Variable Definitions (.tfvars) Files
For setting many variables at once, you can specify their values in a variable definitions file (ending in .tfvars
or .tfvars.json
) and then specify that file on the command line with -var-file
:
$ 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:
image_id = "ami-abc123"
availability_zone_names = [
"us-east-1a",
"us-west-1c",
]
Terraform also automatically loads a number of variable definitions files if they are present:
- Files named exactly
terraform.tfvars
orterraform.tfvars.json
. - Any files with names ending in
.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:
{
"image_id": "ami-abc123",
"availability_zone_names": ["us-west-1a", "us-west-1c"]
}
Environment Variables
Terraform allows you to set your variable values using environment variables. Each environment variable representing a Terraform variable must start with TF_VAR_
followed by the variable name:
$ export TF_VAR_image_id=ami-abc123
$ terraform plan
...
This can be particularly useful when running Terraform in automated environments, or when needing to store sensitive information outside of your configuration.
Variable Definition Precedence
The above mechanisms for setting variables can be used together in any combination. If the same variable is assigned multiple values, Terraform uses the last value it finds, overriding any previous values. Note that the same variable cannot be assigned multiple values within a single source.
Terraform loads variables in the following order, with later sources taking precedence over earlier ones:
- Environment variables
- The
terraform.tfvars
file, if present. - The
terraform.tfvars.json
file, if present. - Any
*.auto.tfvars
or*.auto.tfvars.json
files, processed in lexical order of their filenames. - Any
-var
and-var-file
options on the command line, in the order they are provided.
References