Skip to main content
Terraform providers In this lesson we’ll walk through Terraform providers: what they are, how Terraform discovers and configures them, best practices for versioning, and how to choose between the two primary Azure providers — AzureRM (azurerm) and AzAPI (azapi). You’ll also learn how to handle multiple Azure subscriptions or tenants using provider aliases. Here’s what we will cover:
  • What Terraform providers are and how Terraform uses them to interact with external platforms.
  • How to declare required_providers and apply safe version constraints.
  • A comparison of the AzureRM (azurerm) and AzAPI (azapi) providers and when to use each.
  • How to handle multiple subscriptions/tenants with provider aliases.
The image shows an agenda with two points: understanding Terraform providers and configuring required providers with version constraints. It has a gradient blue background with numbered markers for each agenda point.
Consistent provider configuration and versioning are critical for predictable behavior in teams and CI pipelines. We’ll start with the fundamentals: what a provider is and how Terraform finds and configures them.

What is a Terraform provider?

A provider is a plugin that implements resources and data sources for a target platform. Providers translate HCL into API calls (CRUD operations) against cloud platforms, SaaS services, or HTTP APIs. Common examples:
  • hashicorp/aws — AWS
  • hashicorp/azurerm — Azure Resource Manager
  • azure/azapi — Direct Azure REST API interactions
Key points:
  • Providers are downloaded by terraform init from the Terraform Registry or other configured sources.
  • Each provider exposes resource types and data sources you reference in HCL.
  • You declare provider requirements in the terraform block (required_providers) and configure provider instances with provider blocks.

How Terraform discovers and configures providers

Use the terraform block to declare provider sources and version constraints. Example:
Notes:
  • source points to the namespace/provider on the registry (or to a custom hostname).
  • version constrains which provider versions Terraform will install.
When you run terraform init, Terraform resolves and downloads the provider binaries and records checksums and versions in .terraform.lock.hcl.

Version constraints and best practices

Common constraint styles:
  • Exact: = 3.45.0
  • Tilde (pessimistic): ~> 3.0 — allows >= 3.0.0 and < 4.0.0
Best practices:
  • Pin provider major versions (e.g., ~> 3.0) to avoid surprises from breaking changes.
  • Commit .terraform.lock.hcl to version control to guarantee consistent provider installs across machines and CI.
  • Upgrade providers intentionally: update constraints, run terraform init -upgrade, and test in non-production environments first.
Always commit .terraform.lock.hcl and pin provider versions to ensure reproducible provider installs across developer machines and CI.

Provider configuration and aliases

Provider instances are configured with provider blocks. For azurerm, you typically include an (often-empty) features block:
To manage multiple subscriptions, tenants, or separate credential sets in one configuration, use provider aliases:
Reference an aliased provider on resources using the provider meta-argument:
Passing providers into modules:

AzureRM vs AzAPI: when to use each

Use the table below for a quick comparison and guidance. Examples:
  • AzureRM (preferred when resource is supported and stable):
    • Use azurerm for most production workloads
    • Better ergonomics and state handling
  • AzAPI (use when you need low-level control):
    • Managing preview features or brand-new Azure services not yet modeled in azurerm
    • Applying raw ARM templates or specifying type + API version directly
AzAPI example — creating a VM via raw ARM type and body:
Guidelines:
  • Prefer azurerm for GA resources for better Terraform-native support.
  • Use azapi when you need immediate access to new API versions, preview features, or raw ARM payloads not yet covered by azurerm.
  • It’s common to mix both providers in a single configuration — choose the right tool for the resource and be mindful of implicit dependencies (outputs, references, or ordering) between resources managed by different providers.
When mixing azurerm and azapi, explicitly manage dependencies (e.g., using depends_on) if the ordering matters and verify resource state interactions to avoid drift or race conditions.

Additional operational notes

Summary

  • Providers connect Terraform to external platforms and are required for managing resources.
  • Declare providers via required_providers and configure instances with provider blocks.
  • Pin provider versions and commit .terraform.lock.hcl for reproducibility.
  • Use azurerm for stable, supported Azure resources and azapi for new/preview or niche resources that require direct ARM API access.
  • Use provider aliases to manage multiple subscriptions, tenants, or credential sets in the same configuration.
Practice these concepts with hands-on examples and incrementally apply provider upgrades in isolated environments to validate changes before production deployments.

Watch Video