Terraform
Use input variables to add module arguments
Hands-on: Try the Customize Terraform Configuration with Variables tutorial.
You can add variable blocks to your configuration to define input interface for your module. This lets users pass custom values to your module at runtime.
Terraform sets up resources with hardcoded values the same way every time, making your module inflexible and potentially hard to reuse. If you know a value in your configuration changes between Terraform operations, you can replace that value with a variable block. A variable block lets module consumers customize module behavior without altering the module's source code.
Define variables
Add variables blocks to your root module to let consumers pass values into the module at run time. Defining a variable block in a child module lets a parent module pass values into the child module at run time. Learn more about passing values to child modules.
For example, if your root module has a resource with hardcoded values:
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = "subnet-12345"
tags = {
Environment = "dev"
Name = "dev-web-server"
}
}
Terraform sets up resources with hardcoded values the same way every time, making your module inflexible and potentially hard to reuse. If you know a value in your configuration changes between Terraform operations, you can replace that value with a variable block.
Defining variables gives your module consumer the flexibility to change values at run time. Add a variable block for each input you want to define for your module.
The following example defines instance_type, subnet_id, and environment input variables. These variables lets module consumers specify custom values for customize the instance type, subnet, and deployment environment of your web server at run time:
variable "instance_type" {
type = string
description = "EC2 instance type for the web server"
default = "t2.micro"
}
variable "subnet_id" {
type = string
description = "Subnet ID where the web server will be deployed"
}
variable "environment" {
type = string
description = "Deployment environment name"
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
The environment variable also contains an optional validation block to ensure the value a consumer specifies as the input value meets module requirements. Learn more about validating variable values in your configuration.
Reference variable values
To reference a variable in other parts of your configuration, use var.<NAME> syntax. For example, to make your web server use the new variables, replace the hardcoded values with references to var.instance_type, var.subnet_id, and var.environment:
# ...
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = var.subnet_id
tags = {
Environment = var.environment
Name = "${var.environment}-web-server"
}
}
Module consumers can use the default values for the environment, subnet_id, and instance_type variables in the web configuration or input custom values when they run the configuration. If a variable does not have a default value, such as the subnet_id variable, then Terraform prompts the user to assign a value before it generates a plan.
Sensitive values in variables
If you are defining a variable for sensitive data such as an API key or password, use the sensitive argument to prevent Terraform from displaying the value in CLI output:
variable "database_password" {
type = string
description = "Password for the RDS database instance"
sensitive = true
}
Terraform still stores the values of sensitive variables in your state. You can add the ephemeral argument to your variable configuration to omit the variable from state and plan files. Adding the ephemeral argument does add restrictions to the values you can assign that variable. To learn more about handling sensitive data in your configuration, refer to Manage sensitive data.
To learn more about the best practices of defining variables, refer to the Terraform style guide. To learn more about the variable block, refer to the variable block reference.
Assign values to variables
You can assign values to root module variables through multiple methods, each with different precedence levels. Child modules receive their inputs from a parent module as arguments. To learn more about calling child modules, refer to Modules.
If a module defines a variable without a default argument, Terraform prompts the user to supply a value for that variable before it generates a plan. You can assign variable values in the root module using the following methods:
- HCP Terraform variables and variable sets
- The
-varand-var-fileoptions on the CLI - Variable definition files
- Environment variables
Once you assign a value to a variable, you cannot reassign that variable within the same file. However, if the root module receives multiple values for the same variable name from different sources, Terraform uses the following order of precedence:
- Any
-varand-var-fileoptions on the command line in the order provided and variables from HCP Terraform - Any
*.auto.tfvarsor*.auto.tfvars.jsonfiles in lexical order - The
terraform.tfvars.jsonfile - The
terraform.tfvarsfile - Environment variables
- The
defaultargument of thevariableblock
Values defined in HCP Terraform and on the command line take precedence over other ways of assigning variable values. The variable's default argument is at the lowest level of precedence.
Manage variables in HCP Terraform
HCP Terraform provides the following variable management capabilities:
- Assign values to variables in your configuration through workspaces.
- Group variables into sets that you can apply to multiple workspaces.
- Use access control settings to limit who can view and create new variables.
To learn more about variables in HCP Terraform, refer to the Variables overview.
Command-line variables
Inputting variable values with Terraform CLI commands is useful for one-off deployments or when you need to override specific values without creating new files. You can assign variable values with the Terraform CLI using the -var=<VAR_NAME>=<VALUE> flag:
terraform apply -var="instance_type=t3.medium" -var="environment=prod"
terraform apply -var='subnet_ids=["subnet-12345","subnet-67890"]'
If you are passing complex types through environment variables or command line flags, use proper JSON syntax to comply with the string escaping rules in your shell:
export TF_VAR_complex_config='{"key": "value", "list": ["a", "b"]}'
For readability, and to avoid shell escaping, we recommend setting complex variable values with variable definition files. For more details on shell quoting and the Windows command prompt, refer to Input variables on the command line.
Variable definition files
Variable definition files are ideal for managing different environment configurations and for managing variable values in your version control system. Create a variable definition file to assign multiple variable values in one file.
You can assign values directly to variable names in files with a .tfvars or .auto.tfvars extension. For example, the following file assigns variable values for a production environment:
production.auto.tfvars
instance_type = "t3.large"
environment = "prod"
subnet_ids = ["subnet-12345", "subnet-67890", "subnet-abcdef"]
enable_monitoring = true
Terraform automatically loads variable definition files if it detects any of the following:
- File names ending in
.auto.tfvarsor.auto.tfvars.json - A file named
terraform.tfvars.json - A file named
terraform.tfvars
Terraform loads different variable definition files at different times, and uses the following precedence order for the values assigned in variable definition files:
- Any
*.auto.tfvarsor*.auto.tfvars.jsonfiles in lexical order - The
terraform.tfvars.jsonfile - The
terraform.tfvarsfile
If a file name ends with .json, then Terraform parses that file as a JSON object, using variable names as the root object keys:
{
"image_id": "ami-abc123",
"availability_zone_names": ["us-west-1a", "us-west-1c"]
}
You can also apply a .tfvars variable file directly to the CLI using the -var-file flag:
terraform apply -var-file="production.auto.tfvars"
If your variable definition files contains any sensitive values, ensure you ignore those files in your VCS provider.
Environment variables
Environment variables are useful in CI/CD pipelines when you want to inject configuration values without creating additional files. You can set environment variables using the TF_VAR_ prefix to a variable name:
export TF_VAR_instance_type=t3.medium
export TF_VAR_environment=staging
terraform apply
If you are passing complex types through environment variables or command line flags, use proper JSON syntax to comply with the string escaping rules in your shell:
export TF_VAR_complex_config='{"key": "value", "list": ["a", "b"]}'
For readability, and to avoid shell escaping, we recommend setting complex variable values with variable definition files.
Undeclared variables
Terraform handles setting values for undeclared variables differently depending on how you assign that value:
- Terraform ignores any assigned environment variables that do not have a matching
variableblock. - Terraform warns you if you assign an undeclared variable in a variable definition file, letting you catch accidental misspellings in your configuration or definition files.
- Terraform errors if you attempt to assign a value for an undeclared variable with
-varon the command line.