Terraform Basics

Terraform Basics

What is Terraform?

Terraform is one of the tools that let you configure your infrastructure. With its help, one can create, configure or even destroy cloud infrastructure, be it in Azure, AWS, GCP, and others. In brief, it is used to automate various infra tasks.

Other pointers to cover the definition:

  • Is an open-source tool

  • Uses a declarative configuration language known as HCL (Hashicorp Configuration Language)

Understanding the HCL syntax

<block> <parameters> {
    key1=value1
    key2=value2
}

HCL file consists of blocks and arguments. Block is defined in curly braces and is defined in key-value pairs.
Block contains information about the infra platform and the resources that are to be created.
All of this is defined in the configuration file.
Below is a basic block to create a resource group, MyResourceGroup in Azure:

resource "azurerm_resource_group" "rg" {
  location = "eastus"
  name     = "MyResourceGroup"
}

Time to break it down

  • The beginning of the block contains the Block Name which in this case is 'resource'

  • The second part is the Resource Type which is a fixed value and depends on the type of the provider. It provides two bits of info, first is the provider which in this case is "azurerm" and the second is the resource "resource_group"

  • The third part is the Resource Name which can be named anything of one's choice and is used to identify the resource ("rg")

  • Within the curly braces, arguments are present which are specific to the resource type.

Terraform Workflow

A basic workflow consists of four steps

  1. Write the configuration file - Create a configuration file (one with the extension .tf) and create the blocks for the infrastructure to be set up.

  2. terraform init - Run this command to check the config file and initialize the working directory. It initializes and installs the required provider plugins (If we take the example mentioned above, it will be azurerm in this case)

  3. terraform plan - It will display the execution plan that will be carried out by terraform to create the resources mentioned. It will mention the plan to create, change or destroy the resources according to the infrastructure specified in the config file. This command will not create the resource.

  4. terraform apply - It will create the resources as specified.

Configuration Directory

A terraform configuration directory can have many configuration files. For instance, there can be a file create-rg1.tf to create a resource group in Azure

resource "azurerm_resource_group" "rg1" {
  location = "eastus"
  name     = "MyResourceGroup1"
}

While there can also be another configuration file, create-rg2.tf, to create another resource group.

resource "azurerm_resource_group" "rg2" {
  location = "westus"
  name     = "MyResourceGroup2"
}

Terraform will consider both of these files in the configuration directory.
Another common practice is to combine all of these blocks into a single configuration file as shown below:

resource "azurerm_resource_group" "rg1" {
  location = "eastus"
  name     = "MyResourceGroup1"
}
resource "azurerm_resource_group" "rg2" {
  location = "westus"
  name     = "MyResourceGroup2"
}

This single configuration file can have as many blocks as required. A naming convention is followed for such files and is called main.tf

There are many files created within the directory.

File NamePurpose
main.tfContains resource definition
variables.tfContains variable declaration
outputs.tfContains outputs from resources
provider.tfContains provider definition

Input Variables

Until now, the examples have been using hardcoded values and usage of hard-coded values is not encouraged since it defeats the overall purpose of reusability of the script. One should be able to use the script multiple times based on different inputs provided.

File variables.tf is created which has all the variables defined.

variable "rg_location" {
  default     = "eastus"
}

variable "rg_name" {
  default     = "rg"
}

The keyword variable is used, followed by the name of the variable. In this example, the "rg_location" variable has been used to store the location value for our resource group and "rg_name" has the name of the resource group.
The default parameter has the value of the variable that will be used to create the resource.

To use these variables in our main.tf file, we use the keyword "var" along with the variable name, as shown below:

resource "azurerm_resource_group" "rg" {
  location = var.rg_location
  name     = var.rg_name
}

The variable block uses various parameters

  1. default: Where the default value of the variable is specified

  2. description: An optional parameter which has a description of what the variable is used for

  3. type: Again an optional parameter which enforces the type of variable that is being used. This can be string, number, bool, etc. "Any" is the default type if not specified

Other important types of variables that are used:

  • list: It is a numbered collection of values. The example below displays the declaration and the usage of the variable type list

      #variables.tf
      variable "rg_location" {
        default = ["eastus","westus","centralus"]
        type = list
      }
    
      #main.tf
      resource "azurerm_resource_group" "rg" {
        location = var.rg_location[0]
        name     = "rg1"
      }
    
  • map: Data is represented in the format of key-value pairs when we use the type 'map'

#variables.tf
variable "rg_info" {
  default = {
     "location" = "eastus"
     "name" = "default_rg"
  }
  type = map
}
#main.tf
resource "azurerm_resource_group" "rg" {
  location = var.rg_info["location"]
  name     = var.rg_info["name"]
}
  • set: It is similar to a list but the difference is that a set cannot have duplicate values in it

  • objects: Complex data structures by combining all the variable types that we have.

#variables.tf

variable "rg_config" {
  type = object({
    create_rg = bool
    name      = string
    location  = string
  })
}

rg_config = {
  create_rg = true
  name      = "demo-rg"
  location  = "eastus"
}
  • tuples: This is also similar to the list and consists of a sequence of elements. While a list uses elements of the same variable types, tuples can have elements of different types

      #variables.tf
    
      variable "rg_config" {
        type = tuple([string, number, bool])
        default = ["demo-rg",2,true]
      }
    

Output Variables

Along with input variables, Terraform also supports output variables which are used to store the values of an expression. The syntax is mentioned below:

output "<variable_name>" {
  value = "<variable_value>"
  <arguments>
}

In continuation with the same example, we can create an output block to output the name of the resource group created

#main.tf
resource "azurerm_resource_group" "rg1" {
  location = "eastus"
  name     = "MyResourceGroup1"
}

output "resource_group_name" {
  value = azurerm_resource_group.rg1.name
}

When we run 'terraform apply' after the output block has been created, we can see the output variable printed on the screen.

Another command 'terraform output' will display all the output variables and their value on the screen.