Overview
Previous examples used hard-coded values for resource arguments. To parameterize your configuration, standardize your code, or customize resource arguments at apply time, use variables. Variables let you define values once and reuse them across resources.
Using variables provides:
Increased versatility
Separate configuration data from source code so you can reuse the same Terraform configuration across environments without editing the code.
Improved flexibility
After you declare a variable, you can set its value at apply time via environment variables, CLI options, or variable definition files (
.tfvars). In the following example, the VPC name, description, and CIDR block are hard-coded. You can declare any of these as variables and set them at apply time.
resource "alicloud_vpc" "my_vpc" {
vpc_name = "main-vpc"
cidr_block = "10.0.0.0/16"
description = "my first vpc network"
}Input variable syntax
This section describes how to declare input variables.
Variables are declared in a variable block. You can place them in any .tf file, though it's common to keep them in variables.tf.
The label after variable is the variable's name. When you set variable names, follow these rules:
Uniqueness within the module:
Each variable name must be unique in the current module. Variables declared in child modules do not conflict with variables in their parent; each module has its own namespace.
Avoid keyword‑like names:
Terraform does not reserve keywords for variable names, but using names that overlap with common Terraform terms can be confusing. Avoid names like
count,for_each,depends_on,null, or function names such aslengthandsubstr.
A variable block has no required arguments. If you omit type, the variable accepts any type (any). If you omit default, the variable is required and must be provided at plan/apply time.
type
The type argument constrains the kind of value the variable accepts. Terraform supports primitive types (bool, number, string) and richer types such as list(type), set(type), map(type), object({}), tuple([...]), and any.
bool: binary values like
trueorfalse(unquoted).number: numeric values.
string: text values.
default
default is an argument of the variable block that sets a default value.
To access the value of a variable declared within a module, use the expression var.<name>. 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. If no value is provided, Terraform uses the variable's default.
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 name used in the resource reference. You can override the default via environment variables, variable definition files (for example, terraform.tfvars), or CLI options like -var. For example:
# Override the default using the -var CLI option
$ terraform plan -var vpc_cidr_block="172.16.0.0/16"description
description documents the purpose and expected value of a variable. If a variable has no default, Terraform prompts for a value and displays the description during plan or apply:

Write the description from the user's perspective (what to provide and why), not the maintainer's. Use comments for internal notes rather than putting them in description.
sensitive
sensitive is a Boolean argument that marks a variable's value as sensitive in CLI output. When sensitive = true, Terraform redacts the value in terraform plan and terraform apply output.
This is helpful for values like database credentials, access keys, or passwords. (However, sensitive does not encrypt the state file; sensitive values may still be stored in state. Use secrets management and state protection best practices.)
Example: marking the CIDR block as sensitive hides it in the plan output.
$ 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
The validation block lets you enforce custom rules for input values and contains two arguments: condition, a boolean expression that must evaluate to true, and error_message, the text shown when validation fails (both arguments are required).
In the following example, length and substr ensure vpc_name is longer than four 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."
}
}If you run terraform plan and the input value for vpc_name is my-vpc, the validation fails and Terraform prints the custom error:

Methods for setting variables
You can set variable values at runtime using several methods:
# .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_dicr_block=“172.16.0.0/16”
$ terraform apply
# Default variable file: terraform.tfvars
$ terraform applyYou can use .tfvars files to switch between variable sets and version them alongside your configuration. CLI options are convenient for quick tests. Environment variables work well in scripts and CI/CD pipelines. If a required variable is not set, Terraform prompts for a value in the CLI.
When you need to define many variables—especially complex ones—CLI options become unwieldy. Instead, specify values in a file with a .tfvars or .tfvars.json extension and pass it with -var-file when running terraform plan or terraform apply:
$ terraform plan -var-file my-vars.tfvarsVariable definitions in a .tfvars file use HCL syntax and contain only assignments to variable names. JSON variant files (.tfvars.json) contain a JSON object of variable assignments. If a variable file is named terraform.tfvars, terraform.tfvars.json, *.auto.tfvars, or *.auto.tfvars.json, Terraform loads it automatically for plan and apply, without requiring -var-file. When multiple sources set the same variable, Terraform uses the value from the highest‑priority source. CLI flags (-var and -var-file) override values from automatically loaded files, which override environment variables; defaults are used only if no other value is provided. If you pass multiple -var or -var-file flags, later flags override earlier ones. To override a value from a .tfvars file on the command line:
$ terraform plan -var="vpc_name=my-fisrt-vpc"The plan output will then show vpc_name as my-first-vpc, rather than the value in the .tfvars file.
This approach is common in automated workflows, where -var pulls a value from another environment variable and replaces the value predefined in the variable file.
If a variable is not assigned a value by any method, Terraform prompts you when you run plan or apply. For example, if vpc_name has no default and you do not use -var or -var-file, the CLI asks you to enter a value:

Best practices for variables
We recommend the following when declaring variables:
Parameterize only the values that change for each instance or environment.
Expose variables only when you have a clear use case for varying the value. Avoid over‑parameterizing—keep modules opinionated by default. Adding a variable with a
defaultis typically backward‑compatible; changing a default can affect behavior; removing a variable is a breaking change and should be planned carefully.Use
.tfvarsfiles whenever possible.In the root module, prefer variable files for setting values. Avoid switching between files and CLI flags. Command‑line options (such as
-varand-var-file) are temporary, easy to forget, and cannot be versioned. Variable files (for example,terraform.tfvarsor*.auto.tfvars) are predictable and can be committed to source control.Give variables names that are relevant to their purpose.
For numeric inputs (disk size, memory, durations), include units in the name when practical (for example,
disk_size_gb,bandwidth_mbps,subscription_days). If a provider API uses non‑standard units, this convention clarifies expected inputs. For logical inputs, use positively phrased booleans (for example,enable_ipv6) to simplify conditional logic.Variables must have a description.
Include
descriptionfor everyvariable. Descriptions appear in prompts and generated docs, provide context for new contributors, and improve readability and maintainability. Write descriptions from the user's perspective—what value to supply and why.