Purpose of this file
Pin the required Terraform and provider versions, and configure the Azure provider.
Every other file in this folder assumes a particular version of Terraform and a particular version of the Azure provider are available — versions.tf is where that assumption is written down and enforced. Without it, two people (or a person and a GitHub Actions robot) could quietly end up running slightly different tools against the same infrastructure, which is exactly the kind of inconsistency Terraform is supposed to eliminate.
The full file code sample
terraform/versions.tfterraform {
required_version = ">= 1.7, < 2.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 5.2.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}
provider "azurerm" {
features {}
subscription_id = var.subscription_id
resource_providers_to_register = [
"Microsoft.DBforPostgreSQL",
"Microsoft.ManagedIdentity",
"Microsoft.Web",
]
}
The terraform block tooling requirements
This block doesn't create anything in Azure. It only sets rules for the tools Terraform uses to run this project.
required_version = ">= 1.7, < 2.0"
Requires Terraform version 1.7 or newer, but stops short of the untested 2.0 major version. If someone tries to run this project with Terraform 1.5, or with a future 2.x release, Terraform refuses to continue and explains why — instead of running anyway and possibly behaving unexpectedly.
azurerm = {
source = "hashicorp/azurerm"
version = "~> 5.2.0"
}
Terraform itself doesn't know how to talk to Azure — that knowledge lives in a plugin called a provider. This says: download the official azurerm provider, published by HashiCorp, and use a version compatible with 5.2.0. The ~> symbol means “this version or a later patch/minor release, but not the next major version” — small bug-fix updates are fine, big breaking changes are not applied automatically.
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
A second provider, and a useful illustration that providers aren't only for cloud platforms. random generates values — this project uses it in app_service.tf to create the API's JWT signing key once and remember it, so re-applying doesn't invalidate everyone's tokens.
Adding a provider means the lock file must be regenerated for every platform that runs Terraform, not just yours — see terraform init.
The provider block configuration
Where required_providers says which provider to download, the provider block configures how to use it.
The azurerm provider requires a features block to be present, even when there's nothing to customize inside it. Leaving it empty just means “use the provider's default behavior.”
Azure subscriptions are how Azure separates one customer's (or one team's) resources and billing from everyone else's. This line tells the provider exactly which subscription to create resources in. The actual value comes from a variable (covered on the variables.tf page) rather than being typed directly here, so the same file works for anyone's subscription.
resource_providers_to_register = [ "Microsoft.DBforPostgreSQL", "Microsoft.ManagedIdentity", "Microsoft.Web", ]
Azure subscriptions don't have every possible service switched on by default — each service (PostgreSQL databases, managed identities, web apps, and so on) is its own “resource provider” that has to be registered first. Listing them here tells Terraform to make sure they're registered automatically, instead of leaving a person to discover the missing registration only when a later step fails.
Key terms for beginners
- Provider
- A plugin that teaches Terraform how to talk to a specific platform — here, Azure. Terraform also has providers for AWS, GitHub, and many others, as well as utility providers like
randomthat talk to nothing at all. This project uses two. - Version constraint
- A rule like
~> 5.2.0or>= 1.7, < 2.0that limits which versions of a tool are acceptable, so upgrades happen deliberately instead of by accident. - Resource provider (Azure term)
- Not to be confused with a Terraform provider. This is an Azure-side concept: a category of Azure service (like
Microsoft.Webfor web apps) that a subscription must register before it can create that kind of resource.