Managing your on-premises infrastructure with HashiCorp - Part 4
Wed, 18 Sep 2024 17:09:05 -0000
|Read Time: 0 minutes
This is the fourth blog post in a series with the goal to introduce infrastructure admins and engineers to Terraform. In the series, we are explaining how to use it to manage on-prem physical infrastructure in a data center. It is highly recommended that you quickly review the previous post before proceeding with this one.
- Terraform on-premises infrastructure
- Terraform Dell PowerStore
- Terraform resource dependencies
- Terraform variables
- Terraform Dell PowerMax
In this post, we are going to discuss variables. These make our terraform plans more dynamic and flexible. Until now, we have always been creating the same 8GB volume over and over. If we wanted to create a different size volume, we would have to either modify the file or create a new file that reflects the required size. Variables allow us to make our code more reusable and flexible.
Terraform offers local and input variables. The difference between the two types is important when you have complex plans with multiple “modules”. You can read more about the different types of variables in the Terraform official documentation. In this post we are focusing mainly on input variables.
Single variable and var flag
Variables can be of simple types like string, numbers of boolean, but there are also more complex types like lists, sets, and more. The type is defined by the “type” parameter. Additionally, we have been using the parameter “default” which defines the default value of the variable. This block can go inside the “main.tf” or in the “variables.tf” alongside the connection variables required for the PowerStore provider.
variable "vol_size" {
description = "Size of volume to create"
type = number
default = 8
}
Now, in the resource block we can refer to the variable using the “var.” notation as follows.
resource "powerstore_volume" "testvol" {
name = "alb-tf-testvol"
size = var.vol_size
capacity_unit = "GB"
}
Once the variable is defined in this way, we can override the “default” value at runtime. One way of doing this would be with the “-var” flag.
terraform plan -var "vol_size=16"
As you can see in the output, the volume will be 16GB because the 16 we are specifying in the CLI, overrides the default value of 8 defined in the resource block.
root@alb-terraform:~/powerstore# terraform plan -var "vol_size=16"
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# powerstore_volume.testvol will be created
+ resource "powerstore_volume" "testvol" {
+ app_type = (known after apply)
+ app_type_other = (known after apply)
+ appliance_id = (known after apply)
+ capacity_unit = "GB"
+ creation_timestamp = (known after apply)
+ description = (known after apply)
+ host_group_id = (known after apply)
+ host_id = (known after apply)
+ id = (known after apply)
+ is_replication_destination = (known after apply)
+ logical_unit_number = (known after apply)
+ logical_used = (known after apply)
+ name = "alb-tf-testvol"
+ nguid = (known after apply)
+ node_affinity = (known after apply)
+ nsid = (known after apply)
+ performance_policy_id = "default_medium"
+ protection_policy_id = (known after apply)
+ sector_size = 512
+ size = 16
+ state = (known after apply)
+ type = (known after apply)
+ volume_group_id = (known after apply)
+ wwn = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Tfvars file
In more complex scenarios, we might have many variables like volume name and so on. In that case, we would need to have a separate the “-var” flag for each variable.
terraform plan -var "vol_size=16" -var "vol_name=vol1"
If you have many variables, this method can be tedious. The alternative is to use a “tfvars” file. This is a file that contains multiple variables. For example, we could create “values.tfvars” like in the following:
vol_size = 16
vol_name = "vol1"
In order to use this, let’s define the new variable and change the resource block.
variable "vol_size" {
description = "Size of volume to create"
type = number
default = 8
}
variable "vol_name" {
description = "Name of volume to create"
type = string
default = "testvol1"
}
resource "powerstore_volume" "testvol" {
name = var.vol_name
size = var.vol_size
capacity_unit = "GB"
}
Then, we can invoke it at runtime with the “-var-file” flag.
root@alb-terraform:~/powerstore# terraform plan -var-file values.tfvars
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# powerstore_volume.testvol will be created
+ resource "powerstore_volume" "testvol" {
+ app_type = (known after apply)
+ app_type_other = (known after apply)
+ appliance_id = (known after apply)
+ capacity_unit = "GB"
+ creation_timestamp = (known after apply)
+ description = (known after apply)
+ host_group_id = (known after apply)
+ host_id = (known after apply)
+ id = (known after apply)
+ is_replication_destination = (known after apply)
+ logical_unit_number = (known after apply)
+ logical_used = (known after apply)
+ name = "vol1"
+ nguid = (known after apply)
+ node_affinity = (known after apply)
+ nsid = (known after apply)
+ performance_policy_id = "default_medium"
+ protection_policy_id = (known after apply)
+ sector_size = 512
+ size = 16
+ state = (known after apply)
+ type = (known after apply)
+ volume_group_id = (known after apply)
+ wwn = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Notice how both the values of size and the name in the “values.tfvars” file have overridden the respective default values.
It is important to note that parameters specified with the “-var” flag take precedence. So, in the same variable is defined also in a “tfvars” file then the value defined using “-var” is the one that counts.
Environment variables
Variables can also get their value from the “environment”. Environment variables must follow a strict naming convention. Terraform expects environment variable names to start with the prefix “TF_VAR_”. Otherwise, they won’t be recognized. So, for example, if we want to define the variable “vol_size”, we should create an environment variable named “TF_VAR_vol_size”.
In terms of precedence, environment variables are at the very end, behind “var”, “tfvars”, and even “default”. So, only If the values are not provided in the.tfvars file, or as defaults, or as CLI arguments, it falls back on TF_VAR_ environment variables.
In my plan, I have now commented out the default values for both variables. Let’s define the environment variables and run it again.
root@alb-terraform:~/powerstore# export TF_VAR_vol_size=20
root@alb-terraform:~/powerstore# export TF_VAR_vol_name=envvol
root@alb-terraform:~/powerstore# terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# powerstore_volume.testvol will be created
+ resource "powerstore_volume" "testvol" {
+ app_type = (known after apply)
+ app_type_other = (known after apply)
+ appliance_id = (known after apply)
+ capacity_unit = "GB"
+ creation_timestamp = (known after apply)
+ description = (known after apply)
+ host_group_id = (known after apply)
+ host_id = (known after apply)
+ id = (known after apply)
+ is_replication_destination = (known after apply)
+ logical_unit_number = (known after apply)
+ logical_used = (known after apply)
+ name = "envvol"
+ nguid = (known after apply)
+ node_affinity = (known after apply)
+ nsid = (known after apply)
+ performance_policy_id = "default_medium"
+ protection_policy_id = (known after apply)
+ sector_size = 512
+ size = 20
+ state = (known after apply)
+ type = (known after apply)
+ volume_group_id = (known after apply)
+ wwn = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Environment variables are potentially the safest way to pass credentials to Terraform, like those used by the PowerStore provider. But remember, to do so you must define the variable in your code but not have any default value for it.
Finally, if we don’t provide the values in any of the ways discussed above, Terraform will ask for the values interactively when we run plan and apply. Let’s remove the two environment variables and see what happens.
root@alb-terraform:~/powerstore# unset TF_VAR_vol_size
root@alb-terraform:~/powerstore# unset TF_VAR_vol_name
root@alb-terraform:~/powerstore# terraform plan
var.vol_name
Name of volume to create
Enter a value: newname
var.vol_size
Size of volume to create
Enter a value: 15
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# powerstore_volume.testvol will be created
+ resource "powerstore_volume" "testvol" {
+ app_type = (known after apply)
+ app_type_other = (known after apply)
+ appliance_id = (known after apply)
+ capacity_unit = "GB"
+ creation_timestamp = (known after apply)
+ description = (known after apply)
+ host_group_id = (known after apply)
+ host_id = (known after apply)
+ id = (known after apply)
+ is_replication_destination = (known after apply)
+ logical_unit_number = (known after apply)
+ logical_used = (known after apply)
+ name = "newname"
+ nguid = (known after apply)
+ node_affinity = (known after apply)
+ nsid = (known after apply)
+ performance_policy_id = "default_medium"
+ protection_policy_id = (known after apply)
+ sector_size = 512
+ size = 15
+ state = (known after apply)
+ type = (known after apply)
+ volume_group_id = (known after apply)
+ wwn = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
As expected, it asks us to enter the value for both variables.
Resources
- Part 1: Managing your on-premises infrastructure with HashiCorp Terraform | Dell Technologies Info Hub – Part 1
- Part 2: Managing your on-premises infrastructure with HashiCorp Terraform | Dell Technologies Info Hub – Part 2
- Part 3: Managing your on-premises infrastructure with HashiCorp Terraform | Dell Technologies Info Hub – Part 3
Author: Alberto Ramos, Principal Systems Engineer