Terraform (by HashiCorp) uses HashiCorp Configuration Language (HCL) to provision infrastructure declaratively. Its main power comes from multi-provider support — one workflow for Azure, AWS, GCP, Kubernetes, and hundreds more providers. Unlike ARM and Bicep, Terraform maintains a state file that records what it has deployed, enabling it to calculate a precise diff and show you exactly what will change before applying.
OpenTofu is a community-driven, fully open-source fork of Terraform created in 2023 after HashiCorp relicensed Terraform from MPL to BSL — covered in the next module.
Pros
Multiple providers — manage Azure, AWS, GCP, and on-premises in one tool
Great planning functionality — terraform plan shows an exact diff before any change is made
HCL is one of the better notation methods without using a full programming language
Module support — reusable modules from the Terraform Registry or your own registry
Large ecosystem — thousands of community modules and providers
Drift detection — terraform plan compares state vs live resources
Cons
State store — requires a shared remote backend (e.g. Azure Blob Storage) for team use; state locking is critical
Importing in brown-field environments — terraform import works but mapping existing resources to HCL is tedious
Azure day-0 lag — new Azure features may take days or weeks to appear in the azurerm provider; mitigated by the azapi provider (maintained by Microsoft, day-0 coverage)
BSL license (Terraform ≥ 1.6) — HashiCorp’s license restricts use in competing products (the reason OpenTofu was forked)
terraform plan compares three sources to produce its diff:
Configuration — what your .tf files declare
State file — what Terraform last deployed (.tfstate)
Live infrastructure — the actual current state in Azure (via a refresh)
terraform plan Commands
terraform plan # print to console
terraform plan -out=tfplan # save for later apply
terraform apply tfplan # apply the saved plan exactly, no re-prompt
terraform plan -target=azurerm_storage_account.main # scope to one resource
Plan vs What-If
terraform plan
az deployment ... --what-if
Diff source
State file + live refresh
Azure Resource Manager
Accuracy
High — based on provider knowledge
Moderate — known noisy diffs
Ordering
Shows dependency order
No ordering
Saveable
Yes (-out=tfplan)
No
Apply from saved plan
Yes (terraform apply tfplan)
No
Azure Providers
There are two Terraform providers for Azure:
Provider
Maintained by
Day-0
Field names
azurerm
HashiCorp
No — lag possible
Custom HCL-friendly names
azapi
Microsoft
Yes — same API as ARM/Bicep
Mirror ARM/Bicep API names
See the azapi module for details on using both together.
Your team needs one storage account per environment instead of a single hardcoded one. Convert the resource block below to loop over var.environments with for_each, name each account st${each.key}, and use each.value as its location.