My cloud tutor gave me a scenario for a fictional company, Hagital Cloud Solutions, with one clear goal: use Terraform to provision a Resource Group in Azure and run the complete Infrastructure as Code workflow not just apply and call it a day.
That means:
terraform init - terraform fmt - terraform validate - terraform plan terraform apply
...and then, just as importantly, terraform destroy to tear it all down cleanly.
It's a small task on the surface (one resource, one resource group), but the point wasn't the resource itself it was building the muscle memory for the workflow every Terraform engineer runs on every project, big or small.
Why the Full Workflow Matters
Before jumping into the code, here's the mental model I'm working with for each command:
init — downloads the provider plugins (in this case, azurerm) and sets up the backend. Nothing gets touched in Azure yet.
fmt — auto-formats the .tf files to a consistent style. Cheap to run, keeps code review painless.
validate — checks the syntax and internal logic of the config without talking to Azure. Catches typos and structural mistakes early.
plan — the dry run. Terraform compares your config against the real state of Azure and tells you exactly what it intends to do.
apply — actually executes that plan and creates the resources.
destroy — the reverse of apply; tears down everything Terraform is tracking in state.
The Terraform Code
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.80.0"
}
}
}
provider "azurerm" {
features {}
subscription_id = "Can't put my azure account's subscription id here for security reasons"
}
Resource Group
resource "azurerm_resource_group" "Terraform-RG" {
name = "Terraform-RG"
location = "westeurope"
}
I went with West Europe as the region nothing scenario-specific requiring it, just a solid, low-latency default for this exercise.
Running the Workflow
1. terraform init
Downloaded the azurerm provider and initialized the working directory.
2. terraform fmt
Formatted the file no changes needed since I kept the indentation clean from the start, but good habit to run it anyway.
3. terraform validate
Config passed validation no syntax errors.
4. terraform plan
Terraform showed exactly one resource to be added: azurerm_resource_group.hagital. This is the step I always slow down on reading the plan output line by line before typing yes anywhere.
5. terraform apply
Confirmed the plan, and got the message every Terraform engineer wants to see which is:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
As you can see in my screensnip below...
6. Verified in the azure portal
Jumped into the Azure Portal and confirmed Terraform-rg showing up under Resource Groups state file matched reality.
7. terraform destroy
Since this was a learning exercise not something meant to stay running and accumulate costs i tore it down:
Still verified in the azure portal again:
The screenshot below confirms that the item is no longer available in the portal.
Reflection
This one ran clean end-to-end no errors, no surprises. That's partly luck and partly because the exercise is deliberately scoped small: one resource, one provider, no dependencies to trip over.
But "it worked" isn't really the takeaway I want to hold onto. What stuck with me was the discipline of the workflow fmt and validate before plan and never applying without reading the plan output first. Those are the habits that matter once the configs get bigger and the blast radius of a mistake gets larger.
Next up: I want to extend this into a small VNet + subnet setup on top of the same Resource Group, so I can start tying the networking concepts I've been studying (NSGs, subnet segmentation) into the same IaC workflow.
Top comments (0)