Terraform
Variables
Variables

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:

variables.tf
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:

terraform.tfvars
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:

variables.tf
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:

main.tf
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):

variables.tf
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