My journey learning Terraform to allow me to deploy workloads into Microsoft Azure continues. If you missed the previous posts, please visit the links below.
Part 1: Terraform with Azure – How to install Terraform
Part 2: Terraform with Azure – How to install Azure cli
Part 3: Terraform with Azure – How to Install Visual Studio Code
Part 4: Terraform with Azure – How to install Azure Terraform Plugin in Visual Studio Code
Part 5: Terraform with Azure – Install Git and initialise repository
Part 6: Terraform with Azure – Deploy resources in Azure
Did you know;
1. Terraform is natively available for you to use in the Azure Cloud shell, no installation required.
2.There is a strong relationship between Microsoft and Harshicorp. Microsoft have their own terraform dev team who work closely with Hashicorp.
3. The Terraform registry website includes documentation with sample code so you can get started with deploying resources into Azure quickly.
Part 6 of this blog series involved the deployment of a resource group into Azure using Terraform. In this blog post I go through the process of compiling a variables file.
What is a terraform variables file?
A variables file allows you to write configuration that is easier to re-use as variables can replace hard coded values. It’s ok to use hard coded values if you’re only going to deploy a resource once, however if you wish to deploy a template into different platforms, such as dev, test and production platforms, a variables file would save you the time going through and changing your code. Instead, amending the code in the variables file would be much more convenient.
Example,
If i specified the location of UK South throughout my main.tf file and then decided to deploy the same resources to a different location using the same code in the future, I would have to replace the location throughout my code. The advantage of the variables file is that I only replace the location once as the main.tf file is referencing the variable specified in the variables file.
Below is the code I compiled and deployed to create a resource group in Part 6 of this blog series.
# Create a resource group
resource "azurerm_resource_group" "demo" {
name = "CloudBuild-RG1"
location = "UK South"
}
For now, I will create a variables file including parameters for the location “UK South” and the name of the resource group “CloudBuild-RG1”. I will then replace these default names in my main.tf file, with the name of the variables. Let’s get started.
- Create a new file named variables.tf (The file doesn’t have to be named variables.tf). Terraform scans all files, therefore, will pick up a variables file with a different name.
Note: Notice the green letter “U” by the side of the new file I created? This indicates the file is untracked as I have not committed this version to Git. You’ll also come across the letter “M” which means modified.
2. I now input two variables, my resource group (“CloudBuild-RG1”) and the location of the resource group (“UK South”) as seen in the code below, click save.
When there is a requirement to specify CloudBuild-RG1 in my code, I will instead input the variable name of var.resource_group_name and var.resource_group_location for the resource group location.
variable "resource_group_name" {
default = "CloudBuild-RG1"
type = string
description = "Azure Resource Group Name"
}
variable "resource_group_location" {
default = "UK South"
type = string
description = "Azure Resource Group location"
}
Note:
There are various options available when specifying a ‘type’ value. Further details can be located at the following Terraform link, Types and Values – Configuration Language | Terraform by HashiCorp
3. Next I access the main.tf file and replace location “UK South” with the new variable name var.resource_group_location (var = variable). I also replace the resource group “CloudBuild-RG1” to var.resource_group_name.
Below is a copy of my variables file,
variable "resource_group_name" {
default = "CloudBuild-RG1"
type = string
description = "Azure Resource Group Name"
}
variable "resource_group_location" {
default = "uksouth"
type = string
description = "Azure Resource Group location"
}
and below is a copy of my main.tf file. Variable names highlighted below.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.95.0"
}
}
}
# Configure the Microsoft Azure Provider
provider "azurerm" {
features {}
}
# Create a resource group
resource "azurerm_resource_group" "demo" {
name = var.resource_group_name
location = var.resource_group_location
}
4. Next, i run terraform plan and the results are as expected, no changes will be deployed to Azure as there is nothing further to deploy.
5. Next, as an experiment, I amend my variables.tf file as per the below. I rename RG1 to RG2, and save. I am not amending the code included in file main.tf
Before: default = “CloudBuild-RG1“
After: default = “CloudBuild-RG2“
What do you think the result will be when I run terraform plan?
The resource group can not be renamed, therefore, if the changes were executed, Terraform would destroy resource CloudBuild-RG1 and create a new resource group CloudBuild-RG2.
As you can see from the terraform plan output below, one resource will be added and one destroyed. Not something you would want to perform in production without prior planning/testing!
6. Next, I apply the changes by running terraform apply
Before running terraform apply, I have resource group CloudBuild-RG1 which I deployed via Terraform in part 6 of this blog series. See image below.
After running terraform apply, RG1 has been deleted and a new group ending RG2 deployed. Terraform warns me of the changes I am about to execute, giving me another opportunity to review what will change.
Note: it may take up to 30 seconds before the changes appear in the Azure portal. Click the refresh button.
The result as per the image below. Resource group ending RG1 has gone and RG2 deployed.
You can add new variables to your variables.tf file as and when required. We’ll continue making use of variables as we move on and deploy resources in Azure.
7. Before moving to the next task, I run command terraform destroy which will remove what I have deployed so far, that’s the resource group CloudBuild-RG2.
Reminder: you can always validate your code for errors by using command terraform validate so I would recommend making use of this command as your code grows.
Another quick note, you may have noticed a file named .terraform.tfstate.lock.info appear for a short while as you execute Terraform code.
What is .terraform.tfstate.lock.info?
“If supported by your backend, Terraform will lock your state for all operations that could write state. This prevents others from acquiring the lock and potentially corrupting your state. State locking happens automatically on all operations that could write state. You won’t see any message that it is happening.” Source: Terraform
Back to the command terraform destroy, I run this command and as expected Terraform prompts the changes which will be carried as per the image below. My resource group will be deleted.
8. Type ‘Yes’ to confirm, and after a few seconds, the result.
9. Back to the Azure Portal, browse to resource groups, and a couple of clicks of the refresh button, the resource group has gone. The tfstate file is automatically updated to reflect the changes so if I was to run terraform apply again, the resource group we just destroyed would be recreated.
10. Back to the variables.tf file, let’s perform another task, what if I did not create a default value in my variables file as shown in the code below? At the moment, I have default values, so for example, if I use the variable var.resource_group_name in my main.tf file, the default value of CloudBuild-RG1 will always apply as that’s what I specified in my variables file. The same would apply for the resource group location.
variable “resource_group_name” {default = “CloudBuild-RG2”
type = string
description = “Azure Resource Group Name”
}
variable “resource_group_location” {#default = “uksouth”
type = string
description = “Azure Resource Group location”
}
11. In the next task, I remove the default values so the variables file appears as the one below. I have removed the line that applies a default value.
variable "resource_group_name" {
type = string
description = "Azure Resource Group Name"
}
variable "resource_group_location" {
type = string
description = "Azure Resource Group location"
}
Note: you could also add a # to the beginning of the code so it’s ignore at the time of execution, for example, #default = “CloudBuild-RG2”
12. Save and run the command terraform validate. The configuration is valid.
13. Next, I run terraform plan (This command outputs what Terraform would execute if you were to apply the changes). Ensure you have saved your variables file. Again, as I execute the command, the terraform state lock file will appear temporarily and then disappear.
Tip: you can press the up arrow key on your keyboard to revisit previous commands you have executed.
Reminder: you can use command clear to empty your terminal of previous code.
After running terraform plan, Terraform is not able to locate a default value as I removed the value from my variables file. Terraform prompts for a value, the Azure Resource Group Location as shown below,
I enter uksouth as that’s the Azure region where I wish to deploy my resource group,
14. I am then prompted for a value for my resource group name, I enter, demo-RG1
Note: Terraform will not run the command in the order you specify, however, it will execute the code depending on what is required to be deployed first in Azure.
15. Terraform runs through the plan and provides an output,
Note:
A number of services in Azure require a unique name. For example, a storage account name has to be globally unique, therefore you will only be allowed to create that storage account once. Therefore, a variable would be ideal.
I hope this has been useful. Please feel free to comment below with feedback or any additional information you feel I may have missed out.
In the next blog post I go through the process of compiling a terraform.tfvars file – click the link below to continue,
Part 8: Terraform with Azure – Deploy a terraform.tfvars file
Don’t forget to subscribe to new posts and thank you for following.