Repository: hashicorp/terraform-provider-azurerm

Issue #14588: Consistent Availability Zones across provider
Created: 2021-12-13T08:40:38Z
Community Note

Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request


Background
Azure supports two types of placement of resources: the older Availability Sets and the newer Availability Zones.
Different Azure Regions and different Azure Services may or may not support Availability Zones and/or Availability Sets. The resources which do support Availability Zones either require a single Zone or multiple Zones to be specified depending on the Resource - and different Azure Regions support different Zones (e.g. some support 1 and 2, others 1, 2, and 3, etc.).
As Availability Zones have been rolled out across Azure there's been a couple of changes which means these are implemented inconsistently across the Provider:

Zones initially required 1 element. Over time this has differed per-resource, with some resources taking no zones being specified to mean "Zone Redundant" or "No Zone" depending on the Azure Region the resource is being deployed into.
Resources may have historically required no zone to be specified (and have no zone today) but new resources of that type may require a Zone.

What this means in practice is that using Zones across the provider is inconsistent.
With this feature, we will make the use of Zones consistent across the provider. Going forward:

Resources will allow an element of a single zone or a list of multiple.
We will do away with options like "All Zones" (those using "All Zones" should instead list all zones they desire for the resource).
No zones listed will not imply "zone redundant."


Affected Resources
The following will be changed to allow multiple zones listed:

azurerm_application_gateway
azurerm_dedicated_hardware_security_module
azurerm_firewall
azurerm_kusto_cluster
azurerm_linux_virtual_machine_scale_set
azurerm_nat_gateway
azurerm_redis_enterprise_cache
azurerm_windows_virtual_machine_scale_set
azurerm_kubernetes_cluster
azurerm_managed_disk
azurerm_nat_gateway
azurerm_redis_cache

The following will be changed to allow a single zone listed:

azurerm_dedicated_host_group
azurerm_linux_virtual_machine
azurerm_load_balancer
azurerm_orchestrated_virtual_machine_scale_set
azurerm_mysql_flexible_server
azurerm_postgresql_flexible_server
standby_availability_zone (is Optional & Computed, but should be just Optional)
azurerm_public_ip
azurerm_public_ip_prefix
azurerm_windows_virtual_machine

The following resources aren't yet publicly deprecated, but will be in the future (they're feature-frozen as there are replacements available):

azurerm_virtual_machine
azurerm_virtual_machine_scale_set


Potential Terraform Configuration

TBD
References

While there are differences in the Azure Services here (notably No Zone, Zone Redundant, Single Zone and Multiple Zones), we should consolidate this behavior in Terraform so that it's consistent.

#13505
#13402
#12756
#13445

Duplicate issue #13402: Public IP Zones
Created: 2021-09-17T17:22:30Z
Community Note

Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request


Terraform (and AzureRM Provider) Version


Terraform Core version: [0.12.31]
AzureRM Provider version: [2.72.0]

Terraform Configuration Files

  # azurerm_public_ip.application_gateway_360 will be created
  + resource "azurerm_public_ip" "application_gateway_360" {
      + allocation_method       = "Static"
      + availability_zone       = (known after apply)
      + domain_name_label       = "uw-<snip>-ag-360"
      + fqdn                    = (known after apply)
      + id                      = (known after apply)
      + idle_timeout_in_minutes = 4
      + ip_address              = (known after apply)
      + ip_version              = "IPv4"
      + location                = "westus"
      + name                    = "UW-<snip>-AG-360"
      + resource_group_name     = "UW-<snip>-AG-360"
      + sku                     = "Standard"
      + sku_tier                = "Regional"
      + tags                    = {
          + "Application" = "<snip>"
          + "Environment" = "Prod"
          + "LOB"         = "Diagnostics"
          + "Role"        = "PS360"
        }
      + zones                   = (known after apply)
    }```

### Description / Feedback

Why are we now requiring Availability Zones to be defined for a Public IP? These should be global, not zone specific. Just like Public DNS, one cannot say a DNS Zone will only be available to a specific Data Center.

Furthermore, why do we apparently no longer care about code consistency? Now we have to define "availability_zone" in our code for Terraform to spit out a plan that references "zones" instead.

Furthermore, why are we not following suit with other services that accept a "List" of Availability Zones, Like AKS, Application Gateway, and others? Now we have specify a "string" object of "No-Zone"? This should instead be a empty list `[]`. 

Can we please correct all of these issues? I understand this an Open Source project but we should be maintaining consistency and not adding unnecessary features. 

### References

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip

Closing comment (2022-02-18T09:39:43Z): hi @k7faq @timwebster9
Thanks for opening this issue - apologies for the delayed response here.
As a part of the upcoming v3.0 of the Azure Provider we're looking to make both the identity and zone/zones blocks consistent across the Provider, which is being tracked in #14588.
The specific changes to these blocks can be found in the 3.0 Upgrade Guide but in short we'll be moving towards:

Where a single Availability Zone is available (either Required/Optional), the field will be zone (highlighting that only a single Availability Zone can be configured).
Where multiple Availability Zones can be configured (either Required or where Optional [for Zoneless]) - the field zones will be used.

To deploy a resource into all Zones, each of the Zones will need to be specified (e.g. zones = ["1", "2", "3"])
To deploy a resource into a single Zone, the single Zone should be specified (e.g. zones = ["1"])
To deploy a resource Zoneless, the zones field should be omitted.



This functionality is coming in version 3.0 of the Azure Provider and can be used today by enabling the 3.0 Beta available within v2.97.0 of the AzureRM Provider. Specific instructions on how to opt-into this can be found in the 3.0 Beta Guide - but this'll be enabled by default when v3.0 of the AzureRM Provider ships.
Rather than having multiple issues open tracking the same thing, as #14588 is tracking making zones consistent across the Provider, I'm going to close this issue in favour of that one - would you mind subscribing to #14588 for updates?
Thanks!