Terraform Associate Certification: Variables
Tags: terraform, cloud, aws, devops
Published: 2021-08-23 17:51:35

When using Infrastructure as Code there can be situations in which we need to use the same value multiple times and in different locations, but what if our configuration has changed and we need to modify that value. It can be a little tedious to do, depending upon the number of times that value appears.

Well, in that situations we can use **variables** to have a central source from which we can import the values from 😎.

## How to use them
To use variables we have to create a file in which we will place them. As standard, the file must be named *variables.tf*.
In that file we need to specify the *name of the variable*, *type* (optional) and the *default value* (in case another value is not specified, TF will take the default one).

The syntax is as follows:

![Screen Shot 2021-08-23 at 12.00.18](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxh8vquxttpb85e029kw.png)
 
Once we have declared and defined our variable, we can use it with the next syntax:

![Screen Shot 2021-08-23 at 12.01.18](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7rco6vumwgm2p4dh2fu.png)
 
We just need to type ***var.*** followed by the name of the variable, in this case *instance_type*.

## Multiple approaches to Variable assignment
Variables in Terraform can be assigned values in multiple ways, some of these include:

### 1. Default Variables
If we have a file named *variables.tf* with the variables defined and a default value within it, Terraform will take it in the execution as we did it in the previous example.

*If there is not a default value set to that file, when we run Terraform plan it will prompt to us to set a value to the variable*.

### 2. From a file
As *best practices*, it is recommended to have two files to use variables:
- Variables.tf: in which we need to declare the variables, type and the default value
- Terraform.tfvars: in which we just need to set the value to the variable

So for instance, we can have something like this:

![Screen Shot 2021-08-23 at 12.12.54](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axxtjoyks1gjs4tf9zpk.png)
 
It is important to mention that the *terraform.tfvars* file must not be included in a repository, so it has to be added in a *.gitignore* file.

Also, this file must be named as this, otherwise we need to specify the name of the file in the CLI:

`terraform plan -var-file="custom.tfvars`

### 3. Command line flags
If not explicit value is specified in the terraform.tfvars file, it will take the default one.
We can specify an specific value to variable using something like this in the CLI:

`terraform plan -var="var_name=new_value"`

### 4. Environment variables
In case you don't have a terraform.tfvars defined but you have a variables.tf, we can set the value of the variable using environment variables, we just need to export them with the next structure:

`export TF_VAR_name-of-the-variable=value-of-the-variable`

And when we execute a terraform plan for example, TF will take the value of the exported variable.

## Variables data types
The type argument in a variable block allows us to restrict the type of value that will be accepted as the value for a variable.

If no type constraint is set then a value of any type is accepted.

### Data types:
- **String**: sequence of unicode characters representing some text
- **Number**
- **Collection types**: allows group multiple values of the same type into a single value. The element type is specified as argument:
 - list(...): sequential list of values identified by their position starting with 0, for example ["hello", "world"] in the case of a list(string).
 - map(...): a group of values identified by named labels like {name = "Dan", lastname = "Hdz"} in the case of map(string).
- **Structural types**: allows group multiple values of distinct type into a single value:
 - Object(...): a group of values identified by a key name, it is necessary to specify a schema as argument to indicate the type of values that it is going to store like: *object({name=string, age=number})* and it will match a value with the same structure such as *{name = "Karla", age = 24}* 
 - Tuple(...): A sequence of values. The schema for this must be like tuple *([string, number, bool])* and a value will match if follows that structure such as ["Mike", 23, true]

## Data from maps and list variables
There can be situations in which we have variables defined as map or list and we just need one of those values inside of them.
For example, suppose the next scenario:

![Screen Shot 2021-08-23 at 12.43.42](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/id1zplufud0frytxa0ar.png)
 
In this case, the instance type is going to take the corresponding value for the *"us-west-2"* key (t2.nano).
If we will use a variable type as List, we have to select the position of the element we want like: *instance_type = var.list[0]*

## Closure
Now you are able to use variables in your Terraform configuration files, remember that are different ways to use them, you'll choose which to use depending of the situation 😉.