8i | 9i | 10g | 11g | 12c | 13c | 18c | 19c | 21c | 23c | Misc | PL/SQL | SQL | RAC | WebLogic | Linux

Home » Articles » Misc » Here

Terraform : Variables - A Beginner's Guide

This article gives an overview of input variables in Terraform.

Related articles.

Before We Begin

At first this can seem like a lot of information, but you will probably only use a subset of these variations in your day-to-day operations. For the majority of things I've encountered, I only use basic variables, lists and ".auto.tfvars" files. It's important to know the rest exist, but you probably won't use them very often.

Hardcoded

You don't have to use variables. You can hard code all values, but this makes your scripts less reusable, and potentially exposes sensitive information when your scripts are checked into source control.

Create a directory called "variables-1-hardcoded" and switch to it.

mkdir variables-1-hardcoded
cd variables-1-hardcoded

In the directory create a new file called "main.tf" with the following contents. It defines a single output, which displays a hardcoded value.

output "output1" {
  value = "hardcoded"
}

We initialize the directory.

terraform init

There is nothing to create, but a plan operation will display the hardcoded output.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + output1 = "hardcoded"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Defaults

This time we actually declare a variable and give it a default value. This means we don't have to explicitly assign a value, but we can if the default value is not right for us.

Create a directory called "variables-2-defaults" and switch to it.

mkdir variables-2-defaults
cd variables-2-defaults

In the directory create a new file called "main.tf" with the following contents. It defines a variable with a default value and a single output, which displays a variable value. Notice we reference the variable using the "var." prefix.

variable "my_variable" {
  type    = string
  default = "default-value"
}

output "my_variable_output" {
  value = var.my_variable
}

We initialize the directory.

terraform init

The plan operation will display the variable output.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "default-value"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

-var Flag

We can use the "-var" flag to specify variable values on the command line.

For this example we will use the previous defaults script.

cd variables-2-defaults

We've already initialized the directory, but if you've not followed the article in sequence, you will need to initialise the directory.

terraform init

The plan operation will display the variable output. This time we call the plan command with the "-var" flag to set the variable value.

terraform plan -var="my_variable=melon"

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "melon"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Environment Variables

We can use environment variables to assign values to our Terraform variables. To do this we use environment variable names in the format "TF_VAR_name", where "name" is the Terraform variable name. Terraform recognises this format, and assigns the values accordingly.

For this example we will use the previous defaults script.

cd variables-2-defaults

We set the environment value, using the correct syntax for you operating system.

Rem Windows
set TF_VAR_my_variable=banana

# UNIX/Linux
TF_VAR_my_variable=banana

We've already initialized the directory, but if you've not followed the article in sequence, you will need to initialise the directory.

terraform init

The plan operation will display the variable output. This time we will see the environment variable value, rather than the default value.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "banana"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

terraform.tfvars File

A "terraform.tfvars" file is an alternative to using the "-var" flag or environment variables. The file defines the variable values used by the script. If the file is named "terraform.tvars" it is loaded by default. It's important these files don't get checked into source control, or you are potentially exposing sensitive data.

Create a directory called "variables-3-terraform-tfvars" and switch to it.

mkdir variables-3-terraform-tfvars
cd variables-3-terraform-tfvars

In the directory create a new file called "main.tf" with the following contents. This is a repeat of the previous defaults script.

variable "my_variable" {
  type    = string
  default = "default-value"
}

output "my_variable_output" {
  value = var.my_variable
}

Create a file called "terrafrom.tfvars" with the following contents.

my_variable="apple"

We initialize the directory.

terraform init

The plan operation will display the variable output, using the value from the "terrafrom.tfvars" file.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "apple"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

If you ran the previous test, you will already have the "TF_VAR_my_variable" environment variable defined, but the value from the "terraform.tfvars" file was used in preference.

*.tfvars Files

In some cases you will need multiple variable files. For example, you may wish to keep basic authentication details separate to your variables for building resources. A ".tfvars" file doesn't have to be named "terraform.tfvars", but files named differently will not be loaded by default.

Create a directory called "variables-4-tfvars" and switch to it.

mkdir variables-4-tfvars
cd variables-4-tfvars

In the directory create a new file called "main.tf" with the following contents. This is a repeat of the previous defaults script.

variable "my_variable" {
  type    = string
  default = "default-value"
}

output "my_variable_output" {
  value = var.my_variable
}

Create a file called "my.tfvars" with the following contents.

my_variable="orange"

We initialize the directory.

terraform init

The plan operation will display the variable output.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "banana"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Notice this has used the environment variable setting. The "my.tfvars" file was ignored. To use a file that is not named "terrform.tfvars", we have to explicitly tell terraform to use the file using the "-var-file" flag. This gives us the expected output.

terraform plan -var-file="my.tfvars"

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "orange"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

To apply multiple variable files, we need multiple "-var-file" flags, as shown in the example below.

terraform plan -var-file="my.tfvars" -var-file="provider.tfvars"

*.auto.tfvars Files

An alternative to using the "-var-file" flag is to use a file name with the ".auto.tfvars" extension. This will be loaded automatically, similar to the "terraform.tfvars" file.

Create a directory called "variables-5-auto-tfvars" and switch to it.

mkdir variables-5-auto-tfvars
cd variables-5-auto-tfvars

In the directory create a new file called "main.tf" with the following contents. This is a repeat of the previous defaults script.

variable "my_variable" {
  type    = string
  default = "default-value"
}

output "my_variable_output" {
  value = var.my_variable
}

Create a file called "my.auto.tfvars" with the following contents.

my_variable="grape"

We initialize the directory.

terraform init

The plan operation will display the variable output.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = "grape"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

We can use multiple ".auto.tfvars" files and all will be loaded.

Search/Priority Order

A variable value can be defined in multiple ways, but there is a priority associated with them. It's worth combining the above examples and trying them out for yourself. The search or priority order is as follows.

In most cases I use files with the ".auto.tfvars" extension, as I find this the most convenient.

Sensitive Data

Some variables contain sensitive information we don't want printed out on screen. We can define these variables as sensitive.

Create a directory called "variables-6-sensitive" and switch to it.

mkdir variables-6-sensitive
cd variables-6-sensitive

In the directory create a new file called "main.tf" with the following contents. Notice the variable is defined as sensitive.

variable "my_variable" {
  type      = string
  default   = "default-value"
  sensitive = true
}

output "my_variable_output" {
  value = var.my_variable
}

We initialize the directory.

terraform init

The plan operation would normally display the variable output, but it fails because the variable is marked as sensitive.

terraform plan -var="my_variable=myPassword"

Error: Output refers to sensitive values

  on main.tf line 7:
   7: output "my_variable_output" {

Expressions used in outputs can only refer to sensitive values if the
sensitive attribute is true.

We can prevent the error, whilst maintaining the sensitive nature of the data by marking the output value as sensitive. Amend the "main.tf" file, so that both the variable and output are marked as sensitive.

variable "my_variable" {
  type      = string
  default   = "default-value"
  sensitive = true
}

output "my_variable_output" {
  value     = var.my_variable
  sensitive = true
}

The plan command now completes, but the output value is marked as sensitive.

terraform plan -var="my_variable=myPassword"

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_variable_output = (sensitive value)

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Validations

Create a directory called "variables-7-validations" and switch to it.

mkdir variables-7-validations
cd variables-7-validations

In the directory create a new file called "main.tf" with the following contents. Notice the variable definitions include validations.

variable "my_password" {
  type      = string
  sensitive = true

  validation {
    condition     = length(var.my_password) >= 8
    error_message = "The my_password value must be at least 8 characters long."
  }
}

variable "my_email" {
  type = string

  validation {
    condition     =  can(regex("^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$", var.my_email))
    error_message = "The my_email value must be a valid email address."
  }
}


output "my_password_output" {
  value     = var.my_password
  sensitive = true
}

output "my_email_output" {
  value = var.my_email
}

We initialize the directory.

terraform init

The plan operation would normally display the variable outputs, but it fails on the password validation.

terraform plan -var="my_password=1234" -var="my_email=me@example"

Error: Invalid value for variable

  on main.tf line 1:
   1: variable "my_password" {

The my_password value must be at least 8 characters long.

This was checked by the validation rule at main.tf:5,3-13.

We make the password eight characters long, but now it fails on the email address.

terraform plan -var="my_password=12345678" -var="my_email=me@example"

Error: Invalid value for variable

  on main.tf line 11:
  11: variable "my_email" {

The my_email value must be a valid email address.

This was checked by the validation rule at main.tf:14,3-13.

This time we use a valid password and email address, and the plan is processed successfully.

terraform plan -var="my_password=12345678" -var="my_email=me@example.com"

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_email_output    = "me@example.com"
  + my_password_output = (sensitive value)

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Types and Type Constructors

All the previous examples used basic string type variables, but Terraform supports number and bool types. It also supports type constructors like list, set, map, object and tuple to define complex types. We'll give an example of some of these here.

Create a directory called "variables-8-complex" and switch to it.

mkdir variables-8-complex
cd variables-8-complex

In the directory create a new file called "main.tf" with the following contents. The file defines several types of variables, and accesses their outputs in a number of ways.

# Variables
variable "my_string_variable" {
  type      = string
  default   = "default-value"
}

variable "my_number_variable" {
  type      = number
  default   = 0
}

variable "my_boolean_variable" {
  type      = bool
  default   = false
}

variable "my_list_variable" {
  type      = list(string)
  default   = ["Melon", "Banana", "Apple"]
}

variable "my_object_variable" {
  type       = object({
    name     = string
    quantity = number
  })
  default   = {name:"Melon", quantity:10}
}


# Outputs
output "my_string_variable_output" {
  value = var.my_string_variable
}

output "my_number_variable_output" {
  value = var.my_number_variable
}

output "my_boolean_variable_output" {
  value = var.my_boolean_variable
}

# Whole list.
output "my_list_variable_output" {
  value = var.my_list_variable
}

# First element of list (zero-based).
output "my_list_variable_0_output" {
  value = var.my_list_variable[0]
}

# Whole object.
output "my_object_variable_output" {
  value = var.my_object_variable
}

# Individual elements of object.
output "my_object_variable_name_output" {
  value = var.my_object_variable.name
}

output "my_object_variable_quantity_output" {
  value = var.my_object_variable.quantity
}

We initialize the directory.

terraform init

The plan operation displays all the default values.

terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + my_boolean_variable_output         = false
  + my_list_variable_0_output          = "Melon"
  + my_list_variable_output            = [
      + "Melon",
      + "Banana",
      + "Apple",
    ]
  + my_number_variable_output          = 0
  + my_object_variable_name_output     = "Melon"
  + my_object_variable_output          = {
      + name     = "Melon"
      + quantity = 10
    }
  + my_object_variable_quantity_output = 10
  + my_string_variable_output          = "default-value"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

The outputs are displayed in name order, not in definition order. Notice the complex types like list and object types can be displayed in full, or limited to specific elements. List elements are zero-based, and object elements are named. You can read about the other type constructors here.

For more information see:

Hope this helps. Regards Tim...

Back to the Top.