Azure Terraform: Part 9 – Terraform Variables

Reading Time: 4 minutes

In part 8 of our Terraform journey we covered Terraform Locals, a way of defining a local value and referencing that value within your Terraform code, making your code more flexable.

An alternative approach to defining and referencing a value multiple times within your script is with the use of Terraform variables. Defining variables allows you to infuse external inputs into the magic of Terraform when defining your code.

Join me as we continue of magical journey embracing Terraform Variables, looking at how to craft them and some best practices we can adopt.

Defining Variables

Before you can start defining variables you need to create a variables.tf file within VS Code,

Once created we can begin defining our variables.

Variable Block

Terraform variables provide the capability to allow external inputs to your Terraform script. The values for the variables can be provided by defining a default value within the variables block or providing the value when you run the terraform plan or terraform apply commands. We shall visit both examples and others as we proceed through this chapter.

Defining your variables begins with creating the Variable block. If you have been following along in this series the first resource we defined within our Terraform script was a resource group,

resource "azurerm_resource_group" "ftrg001" {
  name     = "FT23-RG-001"
  location = "uksouth"

  tags = {
    environment = "dev"
  }
}

In our code we have explicitly defined the location as being uksouth.

We can define this as a variable in our variables.tf file,

variable "location" {
  type        = string
  description = "value for location"
}

In the code block above we have named our variable (name label) location, we have defined the data type as string and provided a basic description.

Other types that can be defined are,

  • String: A sequences of characters
  • Number: Number value, whole numbers or decimal numbers
  • Bool: – Boolean value – true/false

For a more comprehensive list and explanation click here

To update our code within our Terraform script to reference the variable we make the following change, var.location. Location being the named we have given to our variable within the variables file,

  • location = var.location
resource "azurerm_resource_group" "ftrg001" {
  name     = "FT23-RG-001"
  location = var.location

  tags = {
    environment = "dev"
  }
}

The azurerm_resource_group resource adapts to the external input provided through the variable var.location.

The keen eyed amongst you might have noticed we have not yet defined a value for this variable. You have several options here, we will look at a few below.

Variables Values

If you run terraform plan from the terminal with your script configured as above you will be asked to provide the value for you variable,

Entering uksouth for the value, Terraform will return “The infrastructure matches your configuration”. We have updated the script to accept external input from the variables.tf file but we have not changed our infrastructure. Our resources are still deployed within the uksouth location, Azure UK South region.

Other input methods to provide a value for your variables are,

  • Declare the value when you run the terraform command (plan or apply)
    • terraform plan -var location=uksouth
  • Define a default value within the variables block,
variable "location" {
  type        = string
  description = "value for location"
  default     = "uksouth"
}
  • Create a terraform.tfvars file and declaring the value,

We can now update out code for all other declared resources to use the variable for location.

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.82.0"
    }
  }
}

provider "azurerm" {
  features {}
}

locals {
  tags = {
    environment = "dev"
  }
}

resource "azurerm_resource_group" "ftrg001" {
  name     = "FT23-RG-001"
  location = var.location

  tags = {
    environment = "dev"
  }
}

resource "azurerm_virtual_network" "ftvnet" {
  name                = "ftvnet01"
  address_space       = ["10.10.0.0/16"]
  location            = var.location
  resource_group_name = azurerm_resource_group.ftrg001.name

  tags = {
    environment = "dev"
  }

}

resource "azurerm_subnet" "ftsubnet" {
  name                 = "ftsubnet01"
  resource_group_name  = azurerm_resource_group.ftrg001.name
  virtual_network_name = azurerm_virtual_network.ftvnet.name
  address_prefixes     = ["10.10.0.0/24"]
}

resource "azurerm_network_security_group" "ftnsg01" {
  name                = "ft-test-nsg01"
  location            = var.location
  resource_group_name = azurerm_resource_group.ftrg001.name

  security_rule = [
    {
      name                                       = "SSH"
      priority                                   = 1001
      direction                                  = "Inbound"
      access                                     = "Allow"
      protocol                                   = "Tcp"
      source_port_range                          = "*"
      destination_port_range                     = "22"
      source_address_prefix                      = "*"
      destination_address_prefix                 = "*"
      description                                = "Allow SSH"
      destination_address_prefixes               = null
      source_application_security_group_ids      = null
      source_port_ranges                         = null
      destination_application_security_group_ids = null
      destination_port_ranges                    = null
      source_address_prefixes                    = null
    },
    {
      name                                       = "RDP"
      priority                                   = 1002
      direction                                  = "Inbound"
      access                                     = "Allow"
      protocol                                   = "Tcp"
      source_port_range                          = "*"
      destination_port_range                     = "3389"
      source_address_prefix                      = "*"
      destination_address_prefix                 = "*"
      description                                = "Allow RDP"
      destination_address_prefixes               = null
      source_application_security_group_ids      = null
      source_port_ranges                         = null
      destination_application_security_group_ids = null
      destination_port_ranges                    = null
      source_address_prefixes                    = null
    }
  ]


  tags = {
    environment = "dev"
  }
}

resource "azurerm_subnet_network_security_group_association" "tfnsg-tfsubnet01" {
  subnet_id                 = azurerm_subnet.ftsubnet.id
  network_security_group_id = azurerm_network_security_group.ftnsg01.id

}

Multiple value can be defined within the variables file and referenced with your Terraform script.

In our variables file i have declared additional variables. Some or all of them can be referenced within our main,tf Terraform file.

For more information about variables you can refer to the Terraform documentation located here.

In Conclusion

As we conclude our exploration of Azure Terraform Variables we learn the magic of variables, the flexibility and consistency they bring to your Terraform script.

In the next chapter of of Azure getting started journey we will look at deploying a VM into the environment we have crafted using all the skills we have gathered on our journey. Hope to see you there.