Day 29: Mastering Terraform Commands Part 2

Adrian Rubico

|

Apr 10, 2025

08:16 PM GMT+8

Day 29: Mastering Terraform Commands Part 2

This blog is a continuation of Day 28: Mastering Terraform Commands Part 1. In this part, we will go further by modifying infrastructure using Terraform commands, introducing variables and outputs, and working with multiple files. By the end of this blog, you will be more comfortable managing infrastructure with Terraform.

Task: Explore Terraform Commands Part 2

Terraform Apply - Update

In this section, we will update the resource group we created previously. We will change the location from "East US" to "West US" in the Terraform configuration file.

hcl
resource "azurerm_resource_group" "example" {
   name     = "example"
   location = "West US" # OR "westus"
   tags = {
     environment = "dev"
   }
}
Terraform Apply, cannot update the location of resource group.

Why does it destroy and recreate?

Terraform treats changes in immutable properties, like location, as destructive changes. The resource group cannot be moved across regions, so Terraform will destroy the old one and create a new one.

💡 In Azure Portal, the location property for a resource group cannot be updated once it is created.

The only thing you can update in a resource group is the tag

If you only want to update tags without affecting the resource group location, modify the tags like below:

hcl
resource "azurerm_resource_group" "example" {
   name     = "example"
   location = "East US" # OR "eastus"
   tags = {
     environment = "production"
   }
}
Terraform Apply, able to update for tags only in resource group.

This will safely update the metadata (tags) without destroying the existing resource group.

Verify in Azure Portal for changes of tags

Verify in the Azure Portal for updated tags.

Terraform Variables

Terraform variables allow you to parameterize values, making your configuration reusable and easier to maintain. Here's an example:

hcl
variable "azregion" {
  type = string
}

resource "azurerm_resource_group" "example" {
  name     = "example-rg"
  location = var.azregion
  tags = {
    environment = "dev"
  }
}

Apply the variable using:

bash
terraform apply -var="azregion=WestUS"
Use terraform apple var manually

Terraform tfvars

The terraform.tfvars file allows you to define variable values separately, making your Terraform commands cleaner and easier to manage. This is especially useful in environments where consistency and reusability are essential.

To avoid passing variables manually each time, define them in a terraform.tfvars file:

hcl
azregion = "WestUS"
Use terraform.tfvars

Terraform will automatically load this file when running commands like terraform plan or terraform apply.

Terraform Locals

Locals let you define values that can be reused throughout your configuration, often used for naming or computed logic.

hcl
locals {
  env = "development"
}

resource "azurerm_resource_group" "example" {
   name     = "example"
   location = "East US" # OR "eastus"
   tags = {
     environment = local.env
   }
}
Use terraform locals

Terraform Outputs

Terraform output values are used to return useful information after applying your configuration.

hcl
output "rg_name" {
  value = azurerm_resource_group.example.name
}
Use terraform output.

Terraform Show

Use terraform show to view the full Terraform state in a readable format. It's useful for reviewing the infrastructure after applying changes.

bash
terraform show
Use terraform show.

Multiple Files in Terraform

Terraform allows splitting configurations across multiple .tf files. These are loaded automatically, improving organization:

  • main.tf: Contains your main resource definitions.
  • variables.tf: Holds all input variable declarations.
  • outputs.tf: Stores output values that you want to extract after provisioning.
  • provider.tf: Defines provider configurations, such as Azure, AWS, GCP, etc.
  • locals.tf: Declares reusable values (locals) to simplify references across your configuration.

This modular approach not only improves readability but also makes your configuration scalable and easier to manage as your infrastructure grows.

Here is the example organized structure with multiple .tf file:

bash
  ├── 01-HelloWorld
  │   ├── main.yml
  │   ├── locals.yml
  │   ├── outputs.yml
  │   └── variables.yml
  │   └── provider.yml

main.tf

hcl
resource "azurerm_resource_group" "example" {
  name     = "rg-example"
  location = var.azregion
  tags = {
    environment = local.env
  }
}

variables.tf

hcl
variable "azregion" {
  type = string
  default = "eastus"
}

outputs.tf

hcl
output "rg_name" {
  value = azurerm_resource_group.example.name
}

provider.tf

hcl
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "4.25.0"
    }
  }
}

provider "azurerm" {
  subscription_id = "YOUR_AZ_SUBSCRIPTION_ID"
  features {}
}

locals.tf

hcl
locals {
  env = "prod"
}

Terraform Destroy

The terraform destroy command removes all resources tracked by your state file.

bash
terraform destroy

⚠️ Warning: This action is irreversible and should be used with caution.

Execute terraform destory

Conclusion

In this blog, we continued our deep dive into Terraform by exploring advanced commands and practices. We covered how to update resources, use variables and tfvars, work with locals and outputs, and organize files more efficiently.

In the next blog, we will learn more about Terraform State management.

Discussion