Terraform 42: A second provider + provider aliases
easy⏱ 5 mincourseterraform
Declare every provider you use
required_providers pins the source and version of each provider. Adding azuread next to azurerm lets one stack create Azure resources and an app registration in Entra ID — different APIs, one terraform apply.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.20"
}
azuread = {
source = "hashicorp/azuread"
version = "~> 2.47"
}
}
}
An app registration in the second provider
With azuread configured, you can register an application and its service principal in code — the identity your service uses. This is the multi-provider payoff: infra and its identity, versioned together.
provider "azuread" {}
resource "azuread_application" "api" {
display_name = "orders-api-dev"
}
resource "azuread_service_principal" "api" {
client_id = azuread_application.api.client_id
}
Aliases: two configs of one provider
Need resources in two subscriptions? Declare a default azurerm plus an aliased one, then point a resource at it with provider = azurerm.hub. Same provider binary, two configurations.
provider "azurerm" {
features {}
}
provider "azurerm" {
alias = "hub"
features {}
subscription_id = var.hub_subscription_id
}
resource "azurerm_dns_a_record" "app" {
provider = azurerm.hub # created in the hub subscription
name = "orders"
zone_name = "example.internal"
resource_group_name = "myorg-hub-dns-rg"
ttl = 300
records = ["10.0.0.10"]
}
Unaliased = default, explicit alias = opt-in
A resource with no provider argument uses the default (unaliased) configuration. Only resources that explicitly set provider = azurerm.hub use the alias. Modules receive aliased providers through a providers = { azurerm = azurerm.hub } block on the module call.
Resolve the provider config
Given resources tagged with an optional alias, write providerFor(res) returning `azurerm.${res.alias}` when an alias is set, else "azurerm" (the default). Log the provider for each resource as name -> provider. A resource with alias: "hub" must resolve to azurerm.hub; one with no alias to azurerm.