Chapter 3: Fundamental Terraform Data Types

In Terraform, there are several fundamental data types that you can use to define your infrastructure as code. Let's describe them and give some examples.

You can use a combination of these data types to create complex data structures. They will be discussed in Chapter 7.

String

A string is a sequence of characters that can be used to represent text or other data. Strings are defined using double quotes (") or single quotes (') and can contain any combination of letters, numbers, and special characters.

Here is an example of string in Terraform:

variable "vm_name" {
  description = "The name of the virtual machine"
  type        = string
  default     = "mytestvm"
}

Number

A number is a numerical value that can be an integer or a floating point number. Numbers are used to represent various types of data in your Terraform configurations, such as quantities, sizes, and durations.

Here is an example of number in Terraform:

variable "vm_count" {
  description = "Number of the VMs to be created"
  type        = number
  default     = 1
}

Bool

A bool is a boolean value that can be either true or false. Bools are used to represent binary data in your Terraform configurations, such as whether a feature is enabled or disabled, or whether a condition is met or not met.

Here is an example of bool in Terraform:

variable "enable_boot_diagnostics" {
  description = "Should Boot Diagnostics be enabled for this Virtual Machine"
  type        = bool
  default     = false
}

List (Tuple)

A list is an ordered collection of values that can be of any data type. Lists are defined using square brackets and separated by commas, like this:

[value1, value2, value3, ...]

For example, you might use a list to define a group of resource groups:

variable "rg_names" {
  description = "List of the VM names"
  type        = list(string)
  default     = ["rg1", "rg2", "rg3"]
}

You can access individual elements of a list using their index, which starts at 0. For example, to access the first element of the rg_names list, you would use rg_names[0].

You can also use the built-in length function to get the number of elements in a list, like this:

count    = length(var.rg_names)

Lists are often used in conjunction with other Terraform features, such as loops and conditionals, to create dynamic infrastructure. For example, you might use a loop to create a resource group resource for each name in the list:

resource "azurerm_resource_group" "default_rg" {
  count    = length(var.rg_names)
  name     = var.rg_names[count.index]
  location = "North Europe"
}

This configuration would create three resource groups, named rg1, rg2, and rg3.

Alternatively, you can define a list of objects and create the resources using the method shown below.

variable "alternative_rg_names" {
  description = "List of the VM names"
  type = list(object({
    name     = string
    location = string
  }))
  default = [
    {
      name     = "alternative_rg1"
      location = "North Europe"
    },
    {
      name     = "alternative_rg2"
      location = "West Europe"
    }
  ]
}

resource "azurerm_resource_group" "alternative_default_rg" {
  count    = length(var.alternative_rg_names)
  name     = var.alternative_rg_names[count.index].name
  location = var.alternative_rg_names[count.index].location
}

count is not the only way to create resources in a loop in Terraform. Details of the loops will be discussed in Chapter 9.

Map (Object)

A map is a collection of key-value pairs that can be used to represent complex data structures. Maps are defined using curly braces and contain a series of key-value pairs, separated by commas. The keys in a map must be unique within the map.

Here is a simple example of how you might use a map in a Terraform configuration for Azure to specify the tags for a resource:

variable "default_tags" {
  description = "Default tags for the resource"
  type        = map(string)
  default = {
    "environment" = "test"
    "provisioner" = "terraform"
  }
}

You can then create a resource group and apply the default tags as shown below:

resource "azurerm_resource_group" "example" {
  name     = "testrg1"
  location = "North Europe"
  tags     = var.default_tags
}

Null

In Terraform, null is a special data type that represents the absence of a value or the unknown value of a variable. null is often used to represent optional values or default values in your Terraform configurations.

Here is a simple example of how you might use null in a Terraform configuration for Azure to specify an optional value:

variable "default_tags" {
  description = "Default tags for the resource"
  type        = map(string)
  default     = null
}

resource "azurerm_resource_group" "example" {
  name     = "testrg1"
  location = "North Europe"
  tags     = var.default_tags
}

If we run terraform plan, we will see that the optional tags property is skipped.

  # azurerm_resource_group.example will be created
  + resource "azurerm_resource_group" "example" {
      + id       = (known after apply)
      + location = "northeurope"
      + name     = "testrg1"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

If you take a look at your state file, you will see it as:

{
  "version": 4,
  "terraform_version": "1.3.7",
  "serial": 6,
  "lineage": "xxx",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "azurerm_resource_group",
      "name": "example",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "xxx",
            "location": "northeurope",
            "name": "testrg1",
            "tags": null,
            "timeouts": null
          },
          "sensitive_attributes": [],
          "private": "xxx"
        }
      ]
    }
  ],
  "check_results": null
}

Last updated