Terraform Variable

Variable can be defined in a variable block in #HashiCorp Configuration Language (HCL) for #HashiCorp Terraform in the file variables.tf. A comprehensive definition for a variable block should look like the following:

variable filename {
  default: "Hello World"
  type: string
  description: "To say hello world to the outside world"
}

The default field defined the default value for the variable filename. This must adhere to the type that you have specified in the field type. description is generally used for documenting. All these arguments are optional, so we can actually define an empty variable block without triggering any warnings or errors.

The values of the variables can be assigned else where. You can put their values inside a file named terraform.tfvars or terraform.tfvars.json, or any file that has post-fix .auto.tfvars or .auto.tfvars.json. The following shows the syntax to define these files, which is similar to of the style of JSON file:

filename = "Hello World"
isComputer = true
total = 45

We can even define the value for the variables using environment variable or the command option -var before running terraform apply. If the environment variable is intended to refer to the variable defined in variables.tf, they need to have a format TF_VAR_{variable name} in order to be recognised by Terraform. In the case of -var, you can simply define them in the style -var {variable name}={value}. For every variable, one -var should be used.

The precedence of defined values for the variables is like this: environment variables has the lowest precedence, next the terraform.tfvars and its JSON counterpart, then auto.tfvars and its JSON counterpart, and -var and -var-file has the highest precedence. Higher precedence of defined values will override the lower one.

If the variable block doesn’t contain the default value of the variable and its value can’t be found in all the method mentioned above, then Terraform will prompt for the value.

To use or import variables into another file, we can utilise the prefix var in the format form of var.{variable name}. For example:

resource "local_file" "example" {
  filename = var.filename
}

Note: There are some variables defined in the resources are read-only, meaning we can’t override or assign values to them.

We could convert the value from the Terraform Providers# using the output block to output the variable onto the screen or be used by external program such as Ansible and shell scripts. It accepts only one parameter, that is the name for the to be defined variable. The mandatory argument for it is value argument, which is used to refer to the value from the resource block. description is a description for this output variable, but it is optional.

output "file_id" {
  value = local_file.example.id
  description = "This is an example usage of output block"
}

Output variables could be inspected using the command terraform output.

Type

There are several types available to enforce type checking for a variable, including string, number, bool, any, list, map, set, object and tuple. We can define it in the field type within the variable block.

list can be treated as typical array, meaning you could access the elements inside the list using the [] syntax with an index number starting at 0.

For list, map and set, we can constrain the type of these collections by using the syntax (). The following code takes advantage of this to restrict the list to only accept boolean type values:

variable a_list {
  default = [true, false, true]
  type = list(bool)
}

set is almost identical to of list, except that it doesn’t allow repeated values. A list could be converted to set with the function toset().

map has a minor differing syntax to list and set. It accepts a key and a value where you can later retrieve it using [] with the key name. This is best shown as an example:

variable a_map {
  default = [
    "key1" = "This is the first value"
    "key2" = "This is the second value"
  ]
  type = map(string)
}

The type object has a similar syntax to map. We can assign multiple types of variable to an object. This is shown as below:

variable an_object {
  default = {
    first-var = "Hello World"
    second-var = 420
    thrid-var = ["cat", "dog", "rat"]
  }
  type = object({
    first-var = string
    second-var = number
    thrid-var = list(string)
  })
}

As you can see, it uses a different bracket {} to define an object. Note that the key name must be the same to the key name declared in the type field.

tuple can be defined to include a collection of variables coming from different types. It uses [] to define the type information of the variables.

variable a_tuple {
  default = [true, "dolphin", 69]
  type = tuple([bool, string, number])
}
Links to this page
  • Terraform Resource Replication

    Within #Terraform Providers, we can define a resource in such a way we could replicate multiple instances of them under different name. A recommended way to do this is by using a Terraform Meta Arguments# for_each. for_each will store a list of values, of type# set or map, into a variable called each.value. The following shows the configuration# example:

  • Terraform Project Structure

    The file main.tf usually contain the main configuration for the infrastructure which could contain definitions of resource. variables.tf is a file that stores defined Terraform Variable# for the project. output.tf will contain outputs from the resources. Last but not least, provider.tf keep provider definitions.

  • HashiCorp Terraform

    One don’t need to run the mentioned two commands in order to find out configuration errors within the project, terraform validate should be enough to do the job. Be aware that the command can’t access any remote service such as remote state and provider APIs, so the values might not be checked. The command terraform show can be used to show the resource’s details defined in the file. Pass the option -json if you want them to be in JSON format. We can inspect all the output variables# or only the specific one, if there’s any, by calling the command terraform output. To show the current required providers for the project, run terraform providers, and we can export these providers into another directory using the subcommand mirrors.

#devops