Variable
Overview
Previous examples used hard-coded values for resource arguments. Input variables let you parameterize your configuration, standardize code, and customize resource properties during the apply step.
Input variables offer the following benefits:
-
Increase reusability
Input variables separate attribute assignments from source code, so you can customize and share the same configuration without altering it.
-
Improve flexibility
After you define a variable, you can set its value at runtime in several ways, including environment variables, CLI options, and key-value files. In the following example, the name, description, and CIDR block are hard-coded. You can declare any of these arguments as variables and specify their values at runtime.
resource "alicloud_vpc" "my_vpc" {
vpc_name = "main-vpc"
cidr_block = "10.0.0.0/16"
description = "my first vpc network"
}
Variable syntax
Declare an input variable using a variable block.
Declare input variables in a variable block. We recommend placing all variable declarations for a module in a single file named variables.tf.
The label following the variable keyword is the variable name. Variable names must follow two rules:
-
Be unique within a module.
A variable name must be unique among all variables in the same module. A variable in a child module can have the same name as a variable in the parent module because they exist in separate scopes.
-
Not be a reserved keyword.
A variable name cannot be one of Terraform's reserved keywords, such as the meta-arguments
countandfor_each.
A variable block can be empty because none of its arguments are required. If you omit a default value, Terraform infers the variable type from the value you provide at runtime.
type
The type argument specifies which value types the variable accepts. Terraform supports the following primitive types:
-
bool: A boolean value, either
trueorfalse(unquoted). -
number: A numeric value.
-
string: A sequence of text characters.
default
The default argument assigns a default value to the variable, making the variable optional.
To access the value of a variable declared within a module, use the expression var.. In the following example, the vpc_cidr_block variable is referenced as var.vpc_cidr_block in the resource block and assigned to the cidr_block argument. The resource uses the default value of the variable, which is enclosed in quotation marks.
resource "alicloud_vpc" "my_vpc" {
vpc_name = "main-vpc"
cidr_block = var.vpc_cidr_block
description = ""
}
variable "vpc_cidr_block" {
default = "10.0.0.0/16"
}
The variable name in the variable block must match the reference in the resource block. You can override the default value through an environment variable, a .tfvars file, or the -var CLI option. For example:
# Override the default value using the -var CLI option
$ terraform plan -var 'vpc_cidr_block=172.16.0.0/16'
description
The description argument documents the variable's purpose. If a variable has no default value, Terraform displays the description when prompting for a value during a plan or apply operation:
$ terraform plan
var.vpc_cidr_block
A CIDR block for the VPC.
Enter a value:
The description string is often included in documentation and should explain the variable's purpose and expected value. Write it from the user's perspective, not the maintainer's. Use code comments for maintainer-facing notes.
sensitive
Setting the sensitive argument to true prevents Terraform from displaying the variable's value in command output or log files. The value is masked in the output of terraform plan and terraform apply.
Use this argument for sensitive information such as database credentials, AccessKey pairs, or login passwords. Marking a variable as sensitive reduces the risk of accidentally exposing confidential data.
In this example, the vpc_cidr_block variable is marked as sensitive. The resource my-vpc uses this variable. When you run terraform plan or apply, the value is not displayed:
$ terraform plan
Terraform will perform the following actions:
# alicloud_vpc.my-vpc will be created
+ resource "alicloud_vpc" "my-vpc" {
+ cidr_block = (sensitive value)
+ create_time = (known after apply)
+ id = (known after apply)
+ status = (known after apply)
+ user_cidrs = (known after apply)
+ vpc_name = "main-vpc"
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
validation
Validate the values assigned to a variable by including one or more validation sub-blocks within the variable block. Each validation block includes a condition argument that specifies the validation rule.
In the following example, the length and substr functions are used as a condition to verify that the value of vpc_name is longer than 4 characters and starts with tf-:
variable "vpc_name" {
validation {
condition = length(var.vpc_name) > 4 && substr(var.vpc_name, 0, 3) == "tf-"
error_message = "The VPC name must start with 'tf-' and be longer than 4 characters."
}
}
When you run terraform plan and enter my-vpc as the value for vpc_name, the validation rule is triggered and returns the specified error message:
Error: Invalid value for variable
on main.tf line 66:
66: variable "vpc_name" {
var.vpc_name is "my-vpc"
The VPC name must start with 'tf-' and be longer than 4 characters.
This was checked by the validation rule at main.tf:67,3-13.
Setting variables
Set variable values at runtime in several ways:
# .tfvars file (recommended)
$ terraform apply -var-file my-vars.tfvars
# CLI option
$ terraform apply -var vpc_cidr_block="172.16.0.0/16"
# Environment variable
$ export TF_VAR_vpc_cidr_block="172.16.0.0/16"
$ terraform apply
# Default variable file terraform.tfvars
$ terraform apply
Use .tfvars files to quickly switch between and version-control sets of variables. CLI options suit quick validations of simple configurations. Environment variables work well in scripts and pipelines. If a required variable is not set by any method, the CLI prompts you for a value.
When you need to define many variables, especially those with complex types, CLI options become unwieldy. Instead, specify variable values as key-value pairs in a file with a .tfvars or .tfvars.json extension, and pass the file with the -var-file option when you run terraform plan or terraform apply:
$ terraform plan -var-file my-vars.tfvars
Variable definitions in files with a .tfvars or .tfvars.json extension follow the same syntax as HCL, but only contain assignments to variable names. Notably, Terraform automatically loads variable files that are named terraform.tfvars, terraform.tfvars.json, .auto.tfvars, or .auto.tfvars.json when you run the plan or apply command, which eliminates the need to use the -var-file option. Definitions in a .tfvars file override the default values of variables and definitions from environment variables. To override the value of a variable from a .tfvars file on the command line, you can use the -var option in the format -var="<variable_name>=<variable_value>". For example, to specify vpc_name as "my-first-vpc" when you run terraform plan, use the following method:
$ terraform plan -var 'vpc_name=my-first-vpc'
The terraform plan output then shows the value of vpc_name as my-first-vpc, not my-vpc as defined in the .tfvars file. This is useful in automated pipelines where you dynamically pass values to the -var flag to override predefined values.
The -var CLI option has the highest precedence and overrides values set by any other method.
If a required variable (one without a default value) is not assigned a value by any method, Terraform prompts you to enter a value when you run plan or apply. For example, if vpc_name has no value assigned, the CLI prompts for input:
$ terraform plan
var.vpc_name
Enter a value:
Best practices
Follow these best practices when declaring variables:
-
Parameterize only what needs to change
Expose a variable only when it needs to change between instances or environments. Avoid over-parameterizing. Adding or changing a variable with a
defaultvalue is backward-compatible, but removing a variable is a breaking change. -
Prefer .tfvars files for root modules
For root modules, use
.tfvarsfiles to set variable values. Avoid alternating between variable files and command-line options. CLI options are temporary, easily forgotten, and cannot be committed to version control. A default variable file is more predictable. -
Name variables according to their purpose
For numeric variables such as disk size, memory size, or payment period, include the unit in the variable name. Alibaba Cloud OpenAPI does not have standard units, so this convention clarifies the expected input unit for maintainers. For logical variables, use a positively-phrased name such as
enable_ipv6to simplify conditional logic. -
Provide a description for every variable
Descriptions are automatically included in documentation and provide context for new developers, which improves the readability and maintainability of your Terraform configuration.