Terraform Variables
Variables in Terraform are essential for any kind of agile coding, as they allow you to create dynamic, reusable code. However, Terraform variables can be a little confusing, especially in terms of the difference between declaration, assignment and evaluation.
Declaration
Before they can be used, Terraform variables must be declared, which is a programming term for announcing a variable and telling Terraform some information about it, without actually giving it a value. This is done like this:
variable "my_var" {
type = string
description = "This is my variable"
default = "nothing"
}
In this block, only the type
element is required, but description
is highly recommended as it makes life a lot easier for anyone (including yourself) who is reading your code in an attempt to understand how it works. Type can be one of:
string
number
bool
list(<TYPE>)
set(<TYPE>)
map(<TYPE>)
object({<ATTR NAME> = <TYPE>, ... })
tuple([<TYPE>, ...])
The default
element gives your variable a default value, should no value be provided for it by some other means (see below). This attribute is optional, but providing it then makes the variable itself optional, as all variables are required to have a value. If a variable has no default value, then one must be provided to it at runtime.
Variables can also be marked as sensitive
(which prevents them being outputted), nullable
such that they can accept null
as a value, and have validation
blocks to check values.
Note: While you can use any .tf file to hold your variable definitions, it is common to collect them together into a file named variables.tf
. This makes finding, changing and adding new variables across your whole folder easier.
Assignment
In Terraform all values must have a value, but how you choose to provide that value can differ based on circumstances. We have already seen that you can assign a variable a default value, which is often enough. However, all variables, whether or not they have a default value, can have their value set as part of the terraform plan
or terraform apply
commands, like this:
terraform plan -var 'my_var=BANANAS'
The -var
parameter of terraform plan
can be repeated as often as is required, and allows you to change the values passed to Terraform each time you run it.
.tfvars files
An alternative to setting variables at runtime is the use of tfvars files. tfvars files are simple text files which contain variables and their values in the form of key=value pairs. Variables referenced in tfvars files must already be declared elsewhere in your tf files, but tfvars files allows you to specify values only, keeping all variable assignments together such that your code can be reused. For example, you might create a tfvars file which looks like this:
contract_id=1-2AB34C
group_id=123456
property_name=my_property
This would require variables (commonly in variables.tf
) to be declared with the same names, like this:
variable "contract_id" {
type = string
description = "Contract ID"
}
variable "group_id" {
type = string
description = "Group ID"
}
variable "property_name" {
type = string
description = "Name for the property to be managed"
}
When running terraform plan
or terraform apply
Terraform will automatically look for any file named exactly terraform.tfvars
and if found load its values. Alternatively, you can specify a tfvars file of another name by the use of the -var-file
parameter, like this:
terraform plan -var-file my_vars.tfvars
Evaluation
Finally, the whole reason to declare and set variables is to use them, which you can in pretty much any field within Terraform. The syntax is:
var.<variable name>
For example, using the variables above you could create an akamai_property
resource like this:
resource "akamai_property" "my_property" {
name = var.property_name
product_id = "Fresca"
contract_id = var.contract_id
group_id = var.groupid
}
Validations
Although not necessary, you can validate the values used for variables. Especially handy if a different team may be creating *.tfvars files. For example you are declaring a variable for the environment, and your infrastructure only has 4 valid environments (dev, qa, int, prod):
variable "env" {
type = string
default = "dev"
validation {
condition = can(index(["dev", "qa", "int", "prod"], var.env))
error_message = "Invalid value for env. Allowed values are dev, int, qa, prod."
}
}
Exercise
New File
Create a variables.tf file which declares the variables edgerc_path
and config_section
, both of type string
. Configure these with descriptions and default values.
Update
Update your provider.tf file to use these variables in the provider "akamai"
block.
Init
Run terraform init
and confirm the provider is installed correctly.
Plan
Run terraform plan
, providing new values for the 2 variables using the -var
syntax. You could run terraform apply
too, but because we are not modifying any resources no changes will be applied anyway.
New File
Create a terraform.tfvars file and use it to set new values for both variables.
Plan
Re-run terraform plan
using this file instead. You could run terraform apply
too, but because we are not modifying any resources no changes will be applied anyway.
Commit
Commit your changes and push them to GitHub.
Hint: If you use terraform.tfvars you don't need to tell Terraform the variable file's name. If you use anything else (.tfvars) you must use -var-file