If you hardcode values in Terraform configuration files, the code is tied to one specific use case. For example, it provisions one type of server in a single location with a fixed operating system.
This works for basic tests, but it is not very flexible. In most projects, you need to reuse the same configuration with different values. Terraform variables let you do that. Instead of editing the configuration each time something changes, you can pass values into it and use the same code in multiple workflows.
Find out how Terraform variables work through practical Bare Metal Cloud server examples.

What Are Terraform Variables?
Terraform variables are named inputs you declare in a variable block. They let you pass values into your configuration instead of hardcoding them. To declare a variable, add a variable block to your configuration and write the variable name in the block label:
variable "hostname" {
description = "The hostname for the deployed Bare Metal Cloud server."
type = string
}
Inside the block, you can include a description, define the expected value type (i.e., string, number, list), or set validation rules.
In this example:
hostnameis the block label and serves as the variable name.descriptionexplains what the variable is used for.typetells Terraform that the value for thehostnamevariable must be a string.
After declaring a variable, you can reference it in your configuration by writing var. before its name. For example, you can use it in a resource block:
resource "pnap_server" "server" {
hostname = var.hostname
}
The var.hostname reference instructs Terraform to use the value provided for the hostname input variable. In practice, a resource block usually references multiple declared variables:
resource "pnap_server" "server" {
hostname = var.hostname
os = var.os
type = var.server_type
location = var.location
ssh_keys = var.ssh_keys
}
When you run the terraform plan or terraform apply command, Terraform reads the configuration, fills in the variable values from the provided sources, and works out what the final resource setting should be.
Note: If you are new to Terraform, learn the basics of HashiCorp Configuration Language (HCL) so your variable and other configuration blocks follow the correct syntax.
How to Assign Variable Values?
Once you declare variables and reference them in your configuration, Terraform needs to get their values from somewhere. There are several ways to provide these values:
- Default values. Use the
defaultargument to add a fallback value in thevariableblock. Terraform uses this value only if no other values are provided. - .tfvars files. Create one or more separate files that store variable values instead of adding them to the main configuration.
- Environment variables. Pass values that are already predefined in your shell or automation environment.
- Command-line options. Pass a value directly when running a Terraform command.
- Interactive CLI prompts. If Terraform cannot find a value in any of the other sources, it asks you to enter one in the terminal.

Setting Default Values
Default values are mainly used for settings that stay the same across most workflows but occasionally need to be overridden.
Terraform uses a default value only when you do not provide a value from another source, like a .tfvars file, command-line option, or environment variable. To add a default value, use the default argument in a variable block:
variable "location" {
description = "The location where the BMC server will be deployed."
type = string
default = "PHX"
}
In this example, Terraform uses PHX as the value for the location variable, unless you provide a different value from another source.
Variable Definition Files
You can store input variable values in separate files called variable definition files. These files usually use the .tfvars extension.
Most people create a file named terraform.tfvars in the root module directory. For example, you can create the file and add the following variables:
hostname = "database-server-02"
location = "PHX"
server_type = "s1.c1.medium"
os = "ubuntu/jammy"
When you run terraform plan or terraform apply, Terraform automatically loads terraform.tfvars and assigns the values in the file to the corresponding declared variables.
Note: Terraform also automatically loads terraform.tfvars.json and any files with .auto.tfvars or .auto.tfvars.json extensions.
You can use a custom name for variable definition files, such as production_server.tfvars or dev_server.tfvars. Terraform does not load custom filenames automatically, so you need to specify the file with the -var-file option when you run Terraform commands:
terraform plan -var-file="production_server.tfvars"
Custom file names are very useful if you need to provide different values for different environments. For example, you can keep development values in one file and production values in another, then select the right file when you run Terraform.
Environment Variables
Terraform can read input variable values from environment variables set in your shell. For this to work, you need to export the environment variable before running Terraform. The environment variable name has to start with TF_VAR_, followed by the name of the declared Terraform variable:
export TF_VAR_[variable_name]="[variable_value]"
For example, if the variable is named location, you can set its value using the following command:
export TF_VAR_location="PHX"
Next, run Terraform as you normally would:
terraform plan
Terraform finds the environment variable and assigns its value to the matching location input variable. This is ideal for scripts because you do not have to include the values directly in the Terraform command.
Command Line Flags
After you declare a variable and reference it in your configuration, you can provide its value from the command line using the -var flag. To pass a variable directly into a Terraform command, enter:
terraform plan -var="hostname=database-server-01"
If you need to provide values for more than one variable, add the -var flag for each one:
terraform plan -var="hostname=database-server-01" -var="location=PHX" -var="server_type=s1.c1.medium" -var="os=ubuntu/jammy"
Do not use this method for sensitive values like passwords or API keys because they may show up in your command history or logs. If you regularly need to pass multiple values, use a .tfvars file because it's easier to read and manage than a long command.
Interactive CLI Prompts
If Terraform cannot find a value for a declared variable from any of the other sources, it prompts you to enter one in the terminal. For example, the following block declares a hostname variable:
variable "hostname" {
description = "The hostname for the deployed Bare Metal Cloud server."
type = string
}
If no value is available when you run terraform plan or terraform apply, Terraform shows an interactive prompt asking for it:
var.hostname
Bare Metal Cloud server hostname.
Enter a value:
Once you enter a hostname, Terraform uses that value for the command you are running.
Interactive prompts can work for small home labs or test environments. But in automated workflows, you should provide the required values ahead of time using .tfvars files, environment variables, or default values. This way, Terraform does not stop to wait for manual input.
Note: The endpoint and region settings in this example are just for illustration. If you want to use phoenixNAP Bare Metal Cloud with Terraform, read our How to Provision Infrastructure with Terraform article for a complete integration guide.
Variable Precedence
Because Terraform receives input variable values from several sources, you can assign different values to the same variable. For example, a variable might have a default value in the configuration, another value in a .tfvars file, and a third value from the command line.

Terraform does not use all these values at the same time. Instead, it follows a set order of precedence and picks the value from the source with the highest priority. The order from lowest to highest precedence is:
1. The default argument in the variable block.
2. Environment variables using the TF_VAR_ prefix.
3. The terraform.tfvars file.
4. The terraform.tfvars.json file.
5. Files ending in auto.tfvars or .auto.tfvars.json.
6. Command-line options passed with -var or -var-file.
For example, you can define the location variable:
variable "location" {
description = "The location where the BMC server will be deployed."
type = string
default = "PHX"
}
The default value is PHX. Terraform uses this value only if no other value is provided. If you also set the same variable in terraform.tfvars:
location = "ASH"
Terraform will use ASH instead of the default value because terraform.tfvars has higher precedence. If you later pass another value from the command line:
terraform plan -var="location=CHI"
Terraform uses CHI for that run because command-line values have higher precedence than values set in terraform.tfvars.
Terraform Variables Examples
The following examples show how variables can make a Bare Metal Cloud server configuration easier to reuse. They use a pnap_server resource, but you can also apply the same variable patterns to resources from other Terraform providers.
Defining Variable Data Types
You can add arguments inside the variable block to describe the variable in more detail and control which types of values are allowed. The type argument tells Terraform what kind of value the variable accepts.
If someone enters the wrong value type, Terraform returns an error that explains that the value does not match the required format.
String Type
Strings appear in most Terraform configurations. You can use them for text-based settings such as hostnames, locations, IP addresses, or resource IDs.
In this example, type = string instructs Terraform to expect a text value for the hostname variable:
variable "hostname" {
description = "Hostname assigned to the Bare Metal Cloud server."
type = string
default = "email-server-01"
}
You can reference the variable in a resource block:
resource "pnap_server" "server" {
hostname = var.hostname
os = var.os
type = var.server_type
location = var.location
ssh_keys = var.ssh_keys
}
Because of the default value, Terraform will set the server hostname to email-server-01. If you try to provide a different data type instead of a string, Terraform returns a type mismatch error. For example:
terraform plan -var='hostname=["email-server-01"]'
The square brackets indicate that the supplied value is a list and not a string. Because hostname expects a string, Terraform cannot use it.
Number Type
Numbers are used for numeric settings like server counts, port numbers, storage capacity, or memory size. In this example, type = number tells Terraform to expect a numeric value for the server_count variable:
variable "server_count" {
description = "The number of Bare Metal Cloud servers to create."
type = number
default = 1
}
You can use this variable in the count argument of a resource block:
resource "pnap_server" "server" {
count = var.server_count
hostname = "email-server-${count.index + 1}"
os = var.os
type = var.server_type
location = var.location
ssh_keys = var.ssh_keys
}
The count = var.server_count argument controls how many server instances Terraform will create. The count.index + 1 expression starts the hostname numbering at 1.
Because of the default value, Terraform creates one server called email-server-1. If you set server_count to a different number, for example, 3:
terraform plan -var="server_count=3"
Terraform plans to create three servers: email-server-1, email-server-2, and email-server-3.
If you provide text that Terraform cannot convert to a number, like "three", it will return a type mismatch error.
Bool Type
The bool data type only accepts true or false values. Use it when a setting has two possible states, such as enabled or disabled. For example, the following variable controls whether monitoring is enabled for the server by default:
variable "enable_monitoring" {
description = "Controls if monitoring for this server is enabled."
type = bool
default = true
}
Here, monitoring is turned on by default. You can disable it by setting the value to false in a .tfvars file or by passing false from the command line:
terraform plan -var="enable_monitoring=false"
If you use a value other than true or false for this variable, you will get a mismatch error.
List Type
The list data type is used when a variable needs to accept several values of the same type in a specific order. For example, list(string) works well for providing multiple public SSH keys:
variable "ssh_keys" {
description = "Public SSH keys used to access the server"
type = list(string)
}
The list(string) type tells Terraform to expect an ordered collection of string values. You can add these values in a .tfvars file:
ssh_keys = [
"ssh-rsa AAAA…",
"ssh-rsa BBBB…"
]
A list keeps values in the order you provide them, so use it when that order matters. Lists can also contain the same value more than once, unlike a set, which removes duplicates.
Set Type
The set type accepts unique values of the same type without keeping track of their order. This set defines Bare Metal Cloud locations where servers should be deployed:
variable "locations" {
description = "Locations where BMC servers will be deployed."
type = set(string)
default = ["PHX", "ASH"]
}
You can use the set with the for_each meta-argument in a resource block:
resource "pnap_server" "server" {
for_each = var.locations
hostname = "email-server-${lower(each.value)}"
os = var.os
type = var.server_type
location = each.value
ssh_keys = var.ssh_keys
}
Terraform creates one server for each location in the set. With the default values, it creates one server in PHX and another in ASH.
Sets are different from lists because they do not keep values in order and only store each value once. If you add the same location more than once, Terraform will still create only one server in that location.
Map Type
Maps connect names, called keys, to values of the same type. You can use a key to look up a value you need. In this example, the server_types map assigns a different Bare Metal Cloud server type to the development, staging, and production environments:
variable "server_types" {
description = "Controls which BMC server type to use for each environment."
type = map(string)
default = {
dev = "s1.c1.medium"
staging = "s1.c2.medium"
prod = "s2.c2.medium"
}
}
variable "environment" {
description = "Environment to deploy."
type = string
default = "dev"
}
You can reference the correct server type by using the environment name as the map key:
resource "pnap_server" "server" {
hostname = var.hostname
os = var.os
type = var.server_types[var.environment]
location = var.location
ssh_keys = var.ssh_keys
}
The var.server_types[var.environment] expression finds the server type for the chosen environment. By default, Terraform will use s1.c1.medium for dev. If you change the environment to prod, it will use s2.c2.medium instead.
Now, if you need to make changes, you only need to edit the environment variable, not the whole resource block.
Object Type
An object type allows you to group several related settings into one value. Each attribute can have its own name and use a different type. For example, you can group the main Bare Metal Cloud server settings into one server_config variable even though they use different data types:
variable "server_config" {
description = "Main Bare Metal Cloud server configuration."
type = object({
hostname = string
os = string
type = string
location = string
ssh_keys = list(string)
})
}
In the .tfvars file, you would provide the values like this:
server_config = {
hostname = "email-server-01"
os = "ubuntu/jammy"
type = "s1.c1.medium"
location = "PHX"
ssh_keys = [
"ssh-rsa AAAA…",
"ssh-rsa BBBB…",
"ssh-rsa CCCC…"
]
}
You can then reference each object attribute in the resource block:
resource "pnap_server" "server" {
hostname = var.server_config.hostname
os = var.server_config.os
type = var.server_config.type
location = var.server_config.location
ssh_keys = var.server_config.ssh_keys
}
Since each attribute has a name, it is easy to see which value controls the hostname, operating system, server type, location, or SSH access.
Tuple Type
A tuple is used when a variable has to have a fixed number of values in a set order. Each position in the tuple expects one data type, while different positions can use different types. For example, you can set the start and end times of a maintenance window as two strings:
variable "maintenance_window" {
description = "The start and end times of a maintenance window."
type = tuple([string, string)]
default = ["01:30", "02:30"]
}
You can access tuple values only by their position number. In Terraform, counting starts at 0:
locals {
maintenance_start = var.maintenance_window[0]
maintenance_end = var.maintenance_window[1]
}
Position [0] contains the start time, while position [1] contains the end time.
Objects are usually easier to understand than tuples because each attribute has a name. Use tuples for small structures or when the number of values is fixed, and each position has a meaning.
Writing Custom Validation Rules
The type argument controls what data type a variable can accept. A validation block goes one step further and checks if the value is acceptable based on a custom constraint.
For example, the following validation block limits the location variable and only allows 5 specific Bare Metal Cloud location codes:
variable "location" {
description = "The locations where BMC servers will be deployed."
type = string
default = "PHX"
validation {
condition = contains (["PHX", "ASH", "CHI", "NLD", "SGP"], var.location)
error_message = "The location must be PHX, ASH, CHI, NLD, or SGP."
}
}
The contains function checks if the provided value appears in the list. If the user enters a different location code, Terraform stops the operation and shows the custom error message.
You can also validate how a value is written. In this example, the validation block prevents the user from providing an empty hostname:
variable "hostname" {
description = "The hostname assigned to the Bare Metal Cloud server."
type = string
validation {
condition = length(trimspace(var.hostname)) > 0
error_message = "The hostname cannot be an empty string."
}
}
Try to keep your validation messages clear. You need to let users know what went wrong and what kind of value they need to provide.
Restricting Values Using RegEx Validation
RegEx validation is used when a text value needs to match a certain pattern. For example, the rule below allows the hostname variable to contain only lowercase letters, hyphens, or numbers:
variable "hostname" {
description = "The hostname to assign to the Bare Metal Cloud server."
type = string
validation {
condition = can(regex("^[a-z0-9-]+$", var.hostname))
error_message = "The hostname can contain only lowercase letters, hyphens, and numbers."
}
}
The following value will pass validation:
hostname = "email-server-01"
This value fails because it contains underscores and uppercase letters:
hostname = "Email_Server_01"
If a value does not pass the validation rule, Terraform will stop the operation and display the custom error message.
Masking Sensitive Variables
If a variable contains sensitive data, like passwords, API tokens, and secret keys, add the sensitive = true argument to its variable block. This prevents Terraform from displaying the value in the CLI output. For example:
variable "pnap_client_secret" {
description = "The phoenixNAP client secret."
type = string
sensitive = true
}
When the variable is used in the configuration, Terraform displays (sensitive value) instead of printing the actual value. This helps prevent accidental leaks in the terminal or logs.
However, sensitive = true only masks the value in Terraform output. Terraform may still store sensitive data in the state or plan file. Anyone with access to those files may still be able to read the value.
Managing BMC API Credentials
BMC API credentials should never be hardcoded in your Terraform configuration files. For instance, avoid setting a client secret as a variable's default value:
variable "pnap_client_secret" {
description = "My phoenixNAP BMC client secret."
type = string
default = "secret-value"
sensitive = true
}
Even though sensitive = true hides the value from standard CLI output, it does not protect secrets if they are committed to version control. It also does not guarantee that the value stays out of Terraform state or plan files.

When working with provider access credentials, you should always follow the authentication method in the provider's documentation. For example, the pnap provider supports the following environment variables:
export PNAP_CLIENT_ID="your-client-id"
export PNAP_CLIENT_SECRET="your-client-secret"
After setting these variables, you can then leave the provider block empty:
provider "pnap" {}
When you run Terraform, the pnap provider will read the credentials from your shell environment. Because they are not written in the Terraform configuration, they are not included in the configuration files or version control.
Passing Variables Dynamically via CI/CD Pipelines
CI/CD pipelines usually send variable values to Terraform when they run. Once you declare input variables in your configuration, the pipeline can set matching environment variables by adding the TF_VAR_ prefix:
export TF_VAR_environment="production"
export TF_VAR_hostname="email-server-01"
export TF_VAR_location="ASH"
When the pipeline runs the following command, Terraform reads these environment variables:
terraform plan -input=false
It connects each environment variable to the matching input variable you declared. For example, TF_VAR_location provides the value for the location variable.
Note: The -input=false option prevents Terraform from showing an interactive prompt. If a required value is missing, the command will fail instead of waiting for someone to enter it.
In actual pipelines, you usually set values in the pipeline settings or job configuration instead of writing export commands manually. A pipeline can also load environment-specific values from a .tfvars file:
terraform plan -input=false -var-file="dev_server.tfvars"
For a production deployment, the pipeline can load a different file:
terraform plan -input=false -var-file="production_server.tfvars"
You can use the same Terraform configuration for multiple environments, while each environment uses its own server settings.
Practical Tip: Using Maps to Manage BMC OS Image Pricing
Some operating systems include a licensing fee in the server price. To keep track of these costs, set up a map to estimate each operating system in your configuration. Start by declaring the operating system variable:
variable "os" {
description = "The operating system to install on the BMC server."
type = string
default = "ubuntu/jammy"
}
Create a map that links each operating system ID to its estimated monthly cost:
variable "os_monthly_costs" {
description = "The estimated monthly OS image cost used for internal planning."
type = map(number)
default = {
"ubuntu/jammy" = 0
"linux/rocky12" = 0
"windows/srv2019std" = 100
}
}
Remember, these amounts are just examples and do not reflect current Bare Metal Cloud prices. Use the selected operating system as the map key:
locals {
selected_os_monthly_cost = lookup(
var.os_monthly_costs,
var.os,
null
)
}
The lookup function finds the cost for the value of var.os. If the operating system is not in the map, it returns null. Now you can display the estimate as an output:
output "estimated_os_monthly_cost_per_server" {
description = "The estimated monthly OS image cost per server."
value = local.selected_os_monthly_cost
}
Server prices and availability can change over time. Be sure to check your BMC Portal and official pricing docs before making any cost-related decisions.
Using .tfvars Files for Staging and Production BMC Infrastructure
One of the simplest ways to manage different environments with Terraform is to reuse the same configuration and provide different values through separate .tfvars files. Here is an example of a staging_server.tfvars file for a staging server:
environment = "staging"
hostname = "staging-database"
location = "ASH"
server_type = "s1.c1.medium"
os = "ubuntu/jammy"
ssh_keys = [
"ssh-rsa AAAA…"
]
A production server usually needs more resources. You can define these values in a production_server.tfvars file:
environment = "production"
hostname = "prod-web"
location = "PHX"
server_type = "s1.c2.medium"
os = "ubuntu/jammy"
ssh_keys = [
"ssh-rsa AAAA…"
]
After you have created separate .tfvars files, you can review the configuration for the staging environment using this command:
terraform plan -var-file="staging_server.tfvars"
To review the production server, enter:
terraform plan -var-file="production_server.tfvars"
In both cases, Terraform uses the same configuration but fills in the values from the variable definition file you select.
Common Problems with Terraform Variables
Most variable errors happen before Terraform creates or changes infrastructure. This is a good thing because it helps you fix input values before Terraform sends requests to the provider. The next section explains the most common issues.
Type Mismatch Errors
A type mismatch occurs when the value assigned to a variable does not match the type Terraform expects. For example, the following variable expects a list of strings:
variable "ssh_keys" {
description = "SSH public keys used to access the server."
type = list(string)
}
This means you also need to write the value as a list in your .tfvars file:
ssh_keys = [
"ssh-rsa AAAA…"
]
If you provide a single string instead, Terraform returns an error because the value is not a list:
ssh_keys = "ssh-rsa AAAA…"
You can run into similar issues with numbers. For example:
variable "server_count" {
description = "The number of BMC servers to create."
type = number
}
The following value is valid because it is a number:
server_count = 4
The next value is invalid because Terraform cannot convert the string "four" into a number:
server_count = "four"
To fix a type mismatch error, check the type argument in the variable block and make sure the value you provide matches the expected type and format.
Troubleshooting Variable Overrides
A variable conflict happens when the same variable gets different values from different sources. When this happens, Terraform does not prompt you to choose which value to use. It follows the order of precedence explained earlier. If Terraform uses a value you did not expect, check where the variable is set.

A good order for troubleshooting is:
1. Review the command you ran and look for -var or -var-file.
2. Look for the variable in .auto.tfvars files in the project directory.
3. Check terraform.tfvars.json.
4. Check terraform.tfvars.
5. Analyze environment variables that start with TF_VAR_.
6. Check the default value in the variable block.
Overriding a value is easy, but it can make troubleshooting confusing. Use command-line options only when you need to override a value for a single run. One way to stay on top of variable overrides is by using separate .tfvars files for each environment.
Missing Required Values in Automated Environments
If you run Terraform in your terminal and it cannot find a value for a required variable, it can ask you to enter one manually.
This is not a good idea in automated workflows like CI/CD pipelines. Pipelines cannot pause and wait for someone to type in missing values like a hostname or location.
This is why these workflows typically disable interactive prompts using the -input=false option:
terraform plan -input=false
Now, if a required value is missing and Terraform cannot prompt for it, the command will fail. To avoid this, you need to make sure the workflow has access to all required values before it runs. For example, you can load values from a variable definition file:
terraform plan -input=false -var-file="production.tfvars"
Another option is to set an environment variable before running Terraform:
export TF_VAR_hostname="dev-web-01"
terraform plan -input=false
If a value is safe to reuse, you can also consider adding a default value in the variable block.
Validation Failures on Custom Rules
A validation rule checks if a variable value meets a custom condition set in the configuration. Even if a value has the correct data type, it can still fail a custom validation rule. For example, the variable below accepts a string, but only certain Bare Metal Cloud locations are allowed:
variable "location" {
description = "The location for deploying Bare Metal Cloud servers."
type = string
validation {
condition = contains (["PHX", "ASH", "CHI", "NLD", "SGP"], var.location)
error_message = "The location must be PHX, ASH, CHI, NLD, or SGP."
}
}
This value passes validation because it is included in the list:
location = "PHX"
This value fails validation because NYC is not one of the allowed locations:
location = "NYC"
To fix a validation error, compare the provided value against the rule in the validation block. If the value is incorrect, replace it with an accepted value. If the rule is outdated or too restrictive, update it to match the current requirements. This is always a better option than removing validation altogether just to get rid of the error.
Accidental Exposure of Secrets in State and Plan Files
When you use the sensitive argument, Terraform hides the value from normal CLI output. However, Terraform may still save the value in state or plan files. If you are not careful, your API keys, access tokens, or passwords could be exposed to anyone with access to these files.

To keep your secrets safe while using Terraform, it is best to use the authentication method your provider recommends. For example, with the pnap provider, you should set your credentials as environment variables:
export PNAP_CLIENT_ID="your-client-id"
export PNAP_CLIENT_SECRET="your-client-secret"
The provider reads these credentials from the environment when Terraform runs. This way, you do not have to put them directly in your Terraform configuration or hardcode them in variable or provider blocks.
Best Practices for Using Terraform Variables
Here are some of the best practices to follow when working with Terraform variables:
- Set a data type for every variable. The
typeargument is optional, but you should include it invariableblocks to clarify what value is expected and to help Terraform detect invalid values while creating a plan. - Add helpful descriptions. The
descriptionargument needs to explain what the variable controls and what kind of value the user should provide. If a value must follow a specific rule, mention that too. - Pick clear variable names. Choose names that make sense at first glance, such as
server_type,server_count, orssh_keys. Avoid abbreviations others may not understand or generic terms likesettingorconfig.

- Make sure value sources are predictable. Try not to assign the same variable in too many places. If a value appears in an environment variable, a .tfvars file, and a command-line option, it can be hard to tell which one Terraform will use. Choose one main source for each workflow, and only use higher-precedence sources when you want to override something on purpose.
- Do not pass provider credentials through input variables. Always check the provider's documentation and use the recommended authentication method. Most often these include environment variables, dynamic credentials, or a protected secret-management system.
- Stick to consistent file naming. A standard approach is to declare input variables in a variables.tf file and store often-used values in terraform.tfvars. If you need to create custom files for different environments, use clear names, like production_server.tfvars or test_database.tfvars.
- Keep validation patterns simple. Try to keep validation and regex patterns as simple as possible. If a rule is hard to read, try breaking it into simpler validation blocks or write a more detailed error message that explains how to fix the value.
Conclusion
You've learned how to declare variables, provide their values, and reference them throughout your configuration. You can now reuse the same code with minimal editing and avoid a lot of repetitive work.
To make your configurations even more flexible, learn how Terraform data sources retrieve information about existing infrastructure and reference it in other parts of your code.



