On this page · 12 sections
- What actually shipped on 27 July 2026
- Change 1: zero Resource Providers register by default
- Change 2: enhanced validation moved, and its defaults flipped
- Change 3: preflight validation is opt-in and covers 6 resources
- Change 4: the legacy App Service and Function App resources are gone
- Change 5: the schema removals that pass review and fail in production
- The upgrade sequence that keeps the estate green
- Should you upgrade now, or wait?
- India-specific considerations
- FAQ
- How eCorpIT can help
- References
Summary. Terraform AzureRM provider 5.0.0 was published on 27 July 2026, and HashiCorp announced general availability the next day, 28 July 2026. The single change most likely to break your pipeline is not a schema edit: the resource_provider_registrations property now defaults to none instead of legacy, so a provider that used to register roughly 60 Azure Resource Providers at startup now registers zero. Version 5.0 also moves the enhanced_validation block inside features, flips location and Resource Provider validation to disabled by default, removes the skip_provider_registration property and the ARM_PROVIDER_ENHANCED_VALIDATION environment variable, and deletes dozens of deprecated resources, including azurerm_app_service, azurerm_app_service_plan and azurerm_function_app. The one genuinely new capability, opt-in preflight validation against Microsoft's Azure Preflight Validation API, currently covers exactly 6 resource types. A patch release, 5.0.1, has since shipped. If you want a disposable place to rehearse the upgrade, HashiCorp's pay-as-you-go tier on the IBM HashiCorp Cloud Platform starts with a $500 credit. Read the five changes below before you bump the constraint.
Most AzureRM major-version write-ups list every removed field and stop there. That list matters, but it is not what breaks teams. What breaks teams is a default that changed quietly, in a subscription where the Terraform service principal never had Microsoft.Something/register/action in the first place, and nobody noticed because version 4.x was papering over it. That is exactly what happened to Resource Provider registration in 5.0.
Terraform on Azure is Microsoft-endorsed tooling, documented on Microsoft Learn, and the AzureRM provider is the most-used way to reach Azure Resource Manager from code. A major version of it is an estate-wide event, not a module-level one.
What actually shipped on 27 July 2026
The 5.0.0 changelog is dated 27 July 2026. Alongside the breaking changes it added a new action, azurerm_web_app_set_slot_distribution, a new data source, azurerm_kubernetes_automatic_cluster_datasource, write-only argument support on azurerm_subnet via network_security_group_id_wo and route_table_id_wo, and Node ~24 support on azurerm_windows_web_app. It also migrated the cdn and sentinel service packages to go-azure-sdk and bumped grpc to 1.82.1. Those are the pleasant parts.
Tiberiu Radu, author of HashiCorp's AzureRM 5.0 release announcement, framed the headline change this way: "In version 5.0, no Resource Providers are registered by default. Users can register only the Resource Providers required by their configuration, retain the legacy behavior, or manage registration outside the provider."
That is the correct design. It is also the change that will fail a first terraform apply in a fresh subscription, because the resource type you are creating now belongs to a Resource Provider nobody registered.
Both HashiCorp and the provider maintainers recommend upgrading Terraform core itself at the same time, and pinning the provider version while you validate.
Change 1: zero Resource Providers register by default
In 4.x, provider initialisation walked a legacy list of roughly 60 Azure Resource Providers and attempted to register any that were not already registered. The upgrade guide gives three reasons that behaviour was retired: it added startup delay from sequential registration checks, it threw permission errors for principals with restricted subscription access, and it registered Resource Providers teams did not want.
In 5.0, resource_provider_registrations defaults to none. The skip_provider_registration property, which many teams had set to true precisely to dodge the permission problem, has been removed outright, so a configuration carrying it will fail to load.
The recommended fix is to name only what you use:
provider "azurerm" {
resource_providers_to_register = [
"Microsoft.Compute",
"Microsoft.Network",
"Microsoft.Storage",
]
features {}
}
If your estate is large enough that enumerating Resource Providers is a project of its own, you can restore 4.x behaviour explicitly in one line:
provider "azurerm" {
resource_provider_registrations = "legacy"
features {}
}
The honest recommendation for most teams is neither of those on day one. Register nothing, run terraform plan across every workspace, and let the failures tell you which Resource Providers your estate genuinely depends on. That list is usually far shorter than 60, and it is a useful artefact in its own right when you are scoping the Terraform service principal's permissions. Platform teams that have already been through a subscription-permission audit as part of a wider cloud cost and governance review will recognise the pattern.
One more consequence worth planning for: if you move registration outside Terraform entirely, someone has to own it. An Azure Policy assignment, a bootstrap pipeline, or a landing-zone module is fine. An undocumented click in the portal is not.
Change 2: enhanced validation moved, and its defaults flipped
The enhanced_validation block has moved inside the features block. Two defaults flipped with it. Location validation and Resource Provider name validation, which cached supported Azure regions and Resource Providers from the Azure MetaData Service, now default to disabled.
The timing consequence is the part to brief your on-call engineers about. With enhanced validation on, an invalid location or Resource Provider name is caught at terraform plan time. With it off, which is now the default, Azure rejects the request at terraform apply time instead. A typo that used to fail in a pull request now fails halfway through a production apply.
HashiCorp gives two reasons for the change: a region may be functional even when it is absent from the ARM region list, and the MetaData Service call adds latency to provider initialisation.
To keep the 4.x behaviour:
provider "azurerm" {
features {
enhanced_validation {
locations = true # Re-enable location validation at plan time
resource_providers = true # Re-enable resource provider validation at plan time
}
}
}
The legacy ARM_PROVIDER_ENHANCED_VALIDATION environment variable has been removed. If your CI sets it, that setting is now silently ignored. Migrate to the enhanced_validation block, or to the two specific variables ARM_PROVIDER_ENHANCED_VALIDATION_LOCATIONS and ARM_PROVIDER_ENHANCED_VALIDATION_RESOURCE_PROVIDERS.
Grep your pipeline definitions for the old variable name before you upgrade. It is the kind of setting that lives in a shared CI template nobody has opened since 2024.
Change 3: preflight validation is opt-in and covers 6 resources
The new capability in 5.0 is preflight validation. With preflight_enabled = true inside the enhanced_validation block, the provider calls the Azure Preflight Validation API at terraform plan time for supported resources, surfacing policy violations, quota breaches and invalid property values before the apply starts.
provider "azurerm" {
features {
enhanced_validation {
preflight_enabled = true # Opt-in: validate supported resource payloads via Azure Preflight API
preflight_location_fallback = "eastus2"
}
}
}
It can also be switched on with ARM_PROVIDER_ENHANCED_VALIDATION_PREFLIGHT_ENABLED.
Read the limits carefully before you sell this internally as a quota-error fix:
- Preflight makes live Azure API calls during
terraform plan, so plan now needs valid Azure credentials. If you run speculative plans in an environment without credentials, this breaks them.
- Only a subset of resource types is supported. Unsupported resources are silently skipped, so a green plan proves nothing about them.
- Arguments that are
(known after apply), such as the output of another resource being created in the same plan, are absent from the preflight request. Validation for those fields is deferred to apply time anyway.
The supported list at 5.0 is short:
| Resource type | Preflight support at 5.0 | Practical value |
|---|---|---|
azurerm_service_plan |
Supported | Catches SKU and quota rejections before apply |
azurerm_app_service_environment_v3 |
Supported | Useful, ASEv3 applies are slow and expensive to retry |
azurerm_dashboard_grafana |
Supported | Catches invalid property values early |
azurerm_managed_redis |
Supported | Useful on capacity-constrained regions |
azurerm_nginx_deployment |
Supported | Catches policy violations early |
azurerm_eventgrid_namespace |
Supported | Catches policy violations early |
| Everything else | Silently skipped | No signal at plan time |
If your expensive failures happen on App Service Environments or Redis, preflight earns its keep immediately. Teams weighing App Service hosting tiers will find this ties directly into the Isolated v4 and ASEv3 cost decision, because a failed ASEv3 apply is one of the slowest feedback loops in Azure. If your estate is mostly virtual machines and networking, preflight changes nothing yet and you can leave it off.
Change 4: the legacy App Service and Function App resources are gone
The 4.x deprecation cycle finally closed. These resources no longer exist in the provider, and a configuration that references one will not load at all:
| Removed in 5.0 | Replacement | Migration shape |
|---|---|---|
azurerm_app_service |
azurerm_linux_web_app, azurerm_windows_web_app |
Split by OS, then terraform state mv |
azurerm_app_service_plan |
azurerm_service_plan |
Rename plus state move |
azurerm_function_app |
azurerm_linux_function_app, azurerm_windows_function_app |
Split by OS, then state move |
azurerm_app_service_slot |
azurerm_linux_web_app_slot, azurerm_windows_web_app_slot |
Split by OS |
azurerm_app_service_active_slot |
azurerm_web_app_active_slot, azurerm_function_app_active_slot |
Split by app type |
azurerm_app_service_hybrid_connection |
azurerm_web_app_hybrid_connection, azurerm_function_app_hybrid_connection |
Split by app type |
azurerm_ai_services |
azurerm_cognitive_account |
Attribute mapping documented in the 4.81.0 docs |
azurerm_redis_enterprise_cluster |
azurerm_managed_redis_cluster |
Rename plus state move |
azurerm_redis_enterprise_database |
azurerm_managed_redis_database |
Rename plus state move |
azurerm_network_packet_capture |
azurerm_virtual_machine_packet_capture, azurerm_virtual_machine_scale_set_packet_capture |
Split by target |
azurerm_restore_point_collection |
azurerm_virtual_machine_restore_point_collection |
Rename plus state move |
A second group has no replacement at all, because the underlying Azure service was retired: the seven azurerm_postgresql_* Single Server resources, five azurerm_hpc_cache_* resources, three azurerm_orbital_* resources, azurerm_batch_certificate, azurerm_maps_creator, azurerm_automation_software_update_configuration, azurerm_security_center_auto_provisioning, azurerm_app_service_source_control_token, and the two azurerm_data_protection_backup_*_postgresql resources. Microsoft documents the Defender for Cloud auto-provisioning retirement in its own Log Analytics agent deprecation plan, and the Azure Maps Creator retirement at aka.ms/AzureMapsCreatorDeprecation.
If you still have azurerm_postgresql_server in state, the provider upgrade is not your problem. The Azure service retirement is. Deal with that first.
The real cost here is usually the state surgery, not the HCL. Each rename is a terraform state mv or an import block plus a removed block, run in a specific order, in a workspace nobody else is applying to at the same time.
Change 5: the schema removals that pass review and fail in production
The removals in change 4 are loud. Your configuration will not even parse. The dangerous class is smaller: renamed or retyped properties on resources you are still using.
Five patterns account for most of them.
Deprecated boolean names replaced by consistent ones. azurerm_virtual_network_gateway and azurerm_virtual_network_gateway_connection both lose enable_bgp in favour of bgp_enabled. azurerm_linux_virtual_machine_scale_set loses automatic_os_upgrade_policy.disable_automatic_rollback for automatic_rollback_enabled and automatic_os_upgrade_policy.enable_automatic_os_upgrade for automatic_os_upgrade_enabled. Note the polarity flip on disable_automatic_rollback: a straight find-and-replace inverts your intent.
Properties that became Required. azurerm_key_vault loses enable_rbac_authorization in favour of rbac_authorization_enabled, and that property is now Required. azurerm_key_vault_certificate_contacts.contact is now Required. On azurerm_kubernetes_cluster, the node_provisioning_profile block is now required. A module that omitted these and relied on a default will not plan.
Types that changed shape. On azurerm_local_network_gateway, address_space is now a Set rather than a List, so it is unordered and you can no longer reference nested items by index. Any address_space[0] reference in your configuration or outputs has to go.
Blocks promoted to their own resources. azurerm_storage_account loses both the queue_properties and static_website blocks, superseded by the standalone azurerm_storage_account_queue_properties and azurerm_storage_account_static_website resources. This is a state move, not an edit.
Security defaults that tighten. On azurerm_storage_account, allow_nested_items_to_be_public now defaults to false, and min_tls_version no longer accepts TLS1_0 or TLS1_1. If a storage account genuinely relied on public nested items, 5.0 will flip it. That is the correct default and it is still a behaviour change you should stage deliberately.
A representative sample of the rename-only changes:
| Resource | Removed property | Use instead |
|---|---|---|
azurerm_log_analytics_workspace |
local_authentication_disabled |
local_authentication_enabled |
azurerm_log_analytics_workspace |
internet_ingestion_enabled |
internet_ingestion_access_type |
azurerm_log_analytics_workspace |
internet_query_enabled |
internet_query_access_type |
azurerm_log_analytics_linked_storage_account |
workspace_resource_id |
workspace_id |
azurerm_monitor_diagnostic_setting |
metric block |
enabled_metric block |
azurerm_monitor_diagnostic_setting |
enabled_log.retention_policy |
Removed, no replacement |
azurerm_virtual_network |
subnet.service_endpoints |
subnet.service_endpoint block |
azurerm_kubernetes_cluster |
default_node_pool.kubelet_config.container_log_max_line |
container_log_max_files |
azurerm_kubernetes_cluster |
default_node_pool.linux_os_config.transparent_huge_page_enabled |
transparent_huge_page |
azurerm_storage_account_customer_managed_key |
key_name, key_vault_id, key_vault_uri |
key_vault_key_id |
azurerm_storage_account |
customer_managed_key.managed_hsm_key_id |
customer_managed_key.key_vault_key_id |
azurerm_container_registry |
trust_policy_enabled |
Removed, no replacement |
The AKS entries matter more than they look. container_log_max_line was renamed to container_log_max_files to match the API property name, and it appears on both azurerm_kubernetes_cluster and azurerm_kubernetes_cluster_node_pool. Clusters running managed Kubernetes upgrades already have enough moving parts, as anyone who worked through the containerd 2.0 migration in Kubernetes 1.35 will remember, so do the provider bump and the cluster upgrade in separate change windows.
The upgrade sequence that keeps the estate green
Pin first. The upgrade guide is explicit about it:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=5.0.0"
}
}
}
provider "azurerm" {
features {}
}
Use the exact-version syntax while you validate, then relax to a ~> 5.0 constraint once every workspace is clean. HashiCorp documents the constraint syntax in the provider requirements reference, and recommends moving to the latest Terraform core at the same time.
A sequence that works on a real estate:
- Inventory before you edit. Run
terraform providersand a repository-wide grep for the removed resource type names. You want the blast radius as a list of workspaces, not a surprise.
- Bump to the last 4.x release first and clear every deprecation warning there. Almost every 5.0 removal was deprecated in 4.x, so a clean 4.x plan is most of the work.
- Grep CI for `ARM_PROVIDER_ENHANCED_VALIDATION` and `skip_provider_registration`. Both are dead in 5.0. One is ignored silently, the other fails to load.
- Pin to `=5.0.0`, set `resource_provider_registrations` explicitly, and run plan-only across every workspace in a non-production subscription.
- Do the state moves in their own change, one resource family at a time. Storage queue properties and static website first, since those are pure moves with no schema thinking attached.
- Re-enable what you actually want. Decide, deliberately, whether
enhanced_validation.locationsgoes back on. For most teams it should. Plan-time errors are cheaper than apply-time errors.
- Turn on preflight last, and only if you run App Service Environments, service plans, Managed Redis, Grafana dashboards, NGINX deployments or Event Grid namespaces. Confirm your plan environment has Azure credentials first.
A patch release, 5.0.1, has since shipped, which is normal for a major provider release. Check the releases page for the current patch before you pin, rather than pinning to =5.0.0 permanently.
If you need somewhere to rehearse that does not touch a shared state file, the pay-as-you-go tier on the IBM HashiCorp Cloud Platform opens with a $500 credit, which is enough to run a throwaway workspace for the duration of a migration.
Should you upgrade now, or wait?
| Situation | Move now | Wait, and why |
|---|---|---|
| Estate is on 4.x with zero deprecation warnings | Yes, this is the cheap path | Nothing to wait for |
Heavy use of azurerm_app_service or azurerm_function_app |
No | Do the 4.x resource split first, then upgrade |
azurerm_postgresql_server still in state |
No | The Azure service is retired; fix that, not the provider |
| Restricted service principal, no registration rights | Yes | 5.0 is the version that stops fighting you |
| Mid-flight AKS cluster upgrade | No | Separate the change windows |
| Speculative plans run without Azure credentials | Yes, but leave preflight off | Preflight needs live credentials at plan time |
The pattern is the same one every major provider bump follows. The version bump is a one-line change. The migration is a state-management project. Teams that decided between Terraform and its fork during the OpenTofu standardisation debate already have the inventory tooling this needs.
India-specific considerations
Three things change the calculus for teams running Azure estates from India.
Region validation and the Central India, South India and West India regions. Turning enhanced validation off is a small risk for teams that mostly deploy to centralindia and southindia, because those region names are stable and well known. The risk rises when a team starts deploying to newer or capacity-constrained regions, where a typo used to be caught at plan time and now surfaces as an apply-time rejection after a partial deployment. Re-enabling enhanced_validation.locations costs one MetaData Service call at provider init and removes that class of failure.
Subscription permissions in Global Capability Centre setups. A common pattern in Indian GCCs is a central cloud team that owns subscription-level rights and product teams that hold only resource-group-level access. Under 4.x, those product teams either set skip_provider_registration = true or lived with registration errors. Under 5.0, the default is finally on their side. The trade is that Resource Provider registration becomes an explicit ticket to the central team the first time a product needs a new Azure service, so agree the SLA for that ticket before you upgrade, not after.
Data residency and the Digital Personal Data Protection Act, 2023. The provider change does not alter where data lives, but the removal of plan-time location validation makes it marginally easier to deploy to the wrong region by accident. If your DPDP posture depends on personal data staying inside Indian regions, that guardrail should not live in the provider at all. Put it in Azure Policy with a deny effect on non-Indian locations, and treat provider-level validation as a convenience rather than a control. Reserved-capacity commitments are region-scoped too, so a stray deployment is a billing problem as well as a compliance one, as the reserved VM instance migration guidance sets out.
FAQ
How eCorpIT can help
eCorpIT runs Azure infrastructure-as-code migrations for product teams that cannot take a week of pipeline downtime to absorb a provider major version. Our platform engineers inventory the estate, clear 4.x deprecations, script the state moves, and stage the provider-level defaults so that plan output stays readable throughout. We are ISO 27001:2022 certified and CMMI Level 5 assessed, and we design Azure deployments aligned with DPDP data-residency requirements. If your AzureRM upgrade has been sitting in the backlog since July, talk to our platform engineering team.
References
- Terraform AzureRM provider 5.0 now generally available - HashiCorp, 28 July 2026
- AzureRM 5.0 upgrade guide (source) - hashicorp/terraform-provider-azurerm
- AzureRM 5.0 upgrade guide (Terraform Registry) - Terraform Registry
- terraform-provider-azurerm v5.0.0 changelog - 27 July 2026
- terraform-provider-azurerm releases - GitHub
- hashicorp/azurerm on the Terraform Registry - Terraform Registry
- Provider requirements and version constraints - HashiCorp Developer
- Install Terraform - HashiCorp Developer
- HashiCorp product pricing - HashiCorp, accessed 8 August 2026
- Overview of Terraform on Azure - Microsoft Learn
- azurerm_ai_services migration to azurerm_cognitive_account - Terraform Registry
- Log Analytics agent auto-provisioning deprecation plan - Microsoft Learn
- Azure Maps Creator deprecation - Microsoft
Last updated: 8 August 2026.