TutorialsTerraform › versions.tf

Terraform Tutorial · File 1 of 9

versions.tf

Pins which version of Terraform itself, and which version of the Azure toolkit (“provider”), this project is built for — and tells that toolkit which Azure subscription and Azure services to work with.

Codey the Sr Developer, standing with a pointer, ready to walk through the guide
Blocks → terraform · provider Defines resources → no Read first → yes

Purpose of this file

Pin the required Terraform and provider versions, and configure the Azure provider.

Codey pointing to the right
the tools this project expects

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_versionTerraform CLI
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.

required_providers → azurermAzure toolkit
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.

required_providers → randomnot every provider is a cloud
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.

features {}required, empty

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.”

subscription_id = var.subscription_idwhich account

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_registerturning on Azure services
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 random that talk to nothing at all. This project uses two.
Version constraint
A rule like ~> 5.2.0 or >= 1.7, < 2.0 that 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.Web for web apps) that a subscription must register before it can create that kind of resource.
Codey giving a thumbs up

Tools pinned and the provider configured — next up is where Terraform keeps its memory.