Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data Source for Availability Zones #3025

Open
bpoland opened this issue Mar 8, 2019 · 16 comments
Open

Data Source for Availability Zones #3025

bpoland opened this issue Mar 8, 2019 · 16 comments

Comments

@bpoland
Copy link

bpoland commented Mar 8, 2019

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
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

When deploying VMs, it would be nice to dynamically get the list of availability zones in the region I'm deploying to. Microsoft's documentation isn't great but it seems that you can only use certain VM SKUs with availability zones, and I found there's an az command that shows the zones for a particular sku:

az vm list-skus --location eastus2 --zone

So, maybe a similar VM SKU related data source would work here. It seems a bit confusing, but I guess that's how Microsoft has organized things...

New or Affected Resource(s)

  • data.azurerm_virtual_machine_sku

Potential Terraform Configuration

data "azurerm_virtual_machine_sku" "test" {
  name     = "Standard_D2s_v3"
  location = "eastus2"
}

Then, in the VM you could set the zone:

zones = "${element(data.azurerm_virtual_machine_sku.test.zones, count.index)}"

(as a side note, I feel like the azurerm_virtual_machine documentation on availability zones is a bit confusing -- why isn't the field just "zone" with a single zone number to put the VM in?)

References

@MattMencel
Copy link
Contributor

Hi @tombuildsstuff is there a technical reason this was pushed to the 2.0.0 milestone? Waiting on API support or something?

I've got a client request for this feature and would be willing to invest some time unless it can't be done at the moment.

@tombuildsstuff
Copy link
Member

hey @MattMencel

is there a technical reason this was pushed to the 2.0.0 milestone? Waiting on API support or something?

From our side we've got plans to write replacements for the VM and VMSS resources in 2.0; coupled with the comment above (which makes a good point: (as a side note, I feel like the azurerm_virtual_machine documentation on availability zones is a bit confusing -- why isn't the field just "zone" with a single zone number to put the VM in?)) - which is a breaking change hence we initially bucketed this for 2.0. However I don't believe there's any technical blockers for adding this new Data Source beforehand (we bucketed this since it's related to the other work).

I've got a client request for this feature and would be willing to invest some time unless it can't be done at the moment.

Awesome - taking a quick look into this it appears the CLI uses this API and there's support for this in the Azure SDK - so I believe it should be possible to add support for this.

The main question from my end is around how we name this resource, (since at first glance it appears this is a Compute specific API, rather than a VM specific API; but perhaps not - it'd be good to confirm if these Zones are the same as the ones available for VMSS's too) - as such perhaps this would make more sense as azurerm_compute_zones - WDYT?

Thanks!

@bpoland
Copy link
Author

bpoland commented Mar 19, 2019

The az cli documentation does mention "compute-related resource SKUs" -- I would assume it would be the same SKUs available for VMSS: https://docs.microsoft.com/en-us/cli/azure/vm?view=azure-cli-latest#az-vm-list-skus

There is an "az vmss list-skus" but it seems to be for getting details about a particular VMSS that's already created: https://docs.microsoft.com/en-us/cli/azure/vmss?view=azure-cli-latest#az-vmss-list-skus

Regarding the name, it does look like the az cli command returns info about disks, availability sets and snapshots as well as virtual machines. And the info returned is not just the available zones. So maybe azurerm_compute_skus ?

@MattMencel
Copy link
Contributor

My impression from looking through the documentation is that availability zones are not necessarily compute specific. The current list of supported services are...

  • Linux Virtual Machines
  • Windows Virtual Machines
  • Virtual Machine Scale Sets
  • Managed Disks
  • Load Balancer
  • Public IP address
  • Zone-redundant storage
  • SQL Database
  • Event Hubs
  • Service Bus (Premium Tier Only)
  • VPN Gateway
  • ExpressRoute
  • Application Gateway (preview)

This is from the az-overview page.

Availability Zones are unique physical locations within an Azure region. Each zone is made up of one or more datacenters equipped with independent power, cooling, and networking. To ensure resiliency, there鈥檚 a minimum of three separate zones in all enabled regions.

So it would be my understanding that these zones aren't unique for VMs or VMSS, but would be the same for all supported services.

The ask here is to get the list of zones in a region correct? So I would probably lean towards describing in the data source name what the intention is.

azurerm_availability_zones or azurerm_region_availability_zones

Or... and I don't even know if this is possible... have an azurerm_region data source where one of the attributes returned is zones.

@bpoland
Copy link
Author

bpoland commented Mar 19, 2019

The thing is, it seems that certain VM SKUs are only available in some of the availability zones (or in none of them). That's why I think you need to look it up by SKU.

From some quick checking, it looks like most SKUs are supported in all AZs but some of the larger ones are sometimes supported in fewer AZs.

@MattMencel
Copy link
Contributor

MattMencel commented Mar 19, 2019

OK, I dug into the API a little bit more and I think I understand better what this requires. Using postman I was able to get a full JSON response from the Compute/ResourceSKUs API. I then used jq to filter out all elements with empty zones in the response body.

cat response.json | jq '.[][] | select((.locationInfo[].zones != null) and (.locationInfo[].zones | length) > 0)

If you filter the response again by | .resourceType there are only two types, "disks" and "virtualMachines".

There's some other capability information in the responses that there may be use cases for. For now though I can try to work on getting a basic data resource that returns the zones for a specific region and VM SKU or disk size. Something like this maybe?

# Virtual Machine Zones
data "azurerm_compute_sku" "vm" {
    type = "vm"
    name = "Standard_D2s_v3"
    location = "centralus"
}

output "azurerm_compute_sku.vm.zones" {
    value = "${data.azurerm_compute_sku.vm.zones}"
}

# Disk Zones
data "azurerm_compute_sku" "disk" {
    type = "disk"
    size = "S4"
    location = "centralus"
}

output "azurerm_compute_sku.disk.zones" {
    value = "${data.azurerm_compute_sku.disk.zones}"
}

Argument Reference

location - (Required) The Azure location where the Compute SKU exists.
type - (Required) Which Compute SKU type to retrieve (disk or vm).
name - (Required for type=vm) The vm SKU.
size - (Required for type=disk) The disk size.

Attributes Reference

zones - A List of availability zones filtered by the criteria above.

@bpoland
Copy link
Author

bpoland commented Mar 19, 2019

Thanks @MattMencel, that would work well for my original use case -- looks good to me!

@Moeser
Copy link
Contributor

Moeser commented Jun 10, 2019

This looks like it would work great. Any progress on a data source for this?

@MattMencel
Copy link
Contributor

I've started working on this. Progress is slow because I'm not a Go developer. I think I'm headed in the right direction, but I've got to figure out how to pull the zone information out. What I'm after is the zones from the ResourceSkuLocationInfo in the SDK.

You can see the branch I'm working on here.... still incomplete.

@gek0
Copy link

gek0 commented Jun 15, 2020

Hoping one day we'll have a normal data resource for this. I'll try to come up with something as soon as I learn Go enough :)

In the meantime, I've come up with my own solution using AZ cli and external modules. Solutions looks/works good enough for now, and should not be much different after data resource is available.

The external module used https://registry.terraform.io/modules/matti/resource/shell/1.0.7 (simple, works great and no infinite plan/apply issues)

Code example:

module "availability_zones_calculator" {
  source  = "matti/resource/shell"
  version = "1.0.7"

  command = "az vm list-skus --location $REGION --zone --resource-type virtualMachines --size $INSTANCE_TYPE --query '[].locationInfo[0].zones' --output jsonc"
  environment = {
    REGION        = data.azurerm_resource_group.resource_group.location
    INSTANCE_TYPE = var.instance_type
  }
}
locals {
  vm_availability_zones = sort(flatten(jsondecode(module.availability_zones_calculator.stdout)))
}

Output is list(string) of sorted strings, aka. available zones for that VM tier/location for eg. ["2", "3"] and easy to use in managed disks/virtual machines resources.
Hope somebody finds it useful 馃檪

@surajmuthreja

This comment has been minimized.

@clemlesne
Copy link

clemlesne commented Jun 15, 2023

I strongly support this. Maybe something similar, to the way AWS done the trick with aws_region..

And what about the resource azurerm_zones from this post?

@HappyTobi
Copy link
Contributor

@clemlesne @tombuildsstuff

I requested a hashicorp azure SDK update, to improve / extend the existing implementation for the azurerm_extended_locations data source.
The idea is, that the data service provide more additional information like zones etc.

See also:
Azure Rest documentation

@clemlesne
Copy link

From a developer perspective, it would be useful to have something like:

Named azurerm_region, would make more sense than azurerm_locations (what is a "location"?).

Example usage:

data "azurerm_region" "current" {}

Arguments:

  • exclude_zone_ids - (Optional) List of Availability Zone IDs to exclude.
  • exclude_zone_names - (Optional) List of Availability Zone names to exclude.
  • id - (Optional) ID of the region to select. By default, it will be the current one. Cannot be paired with name argument.
  • name - (Optional) Full name of the region to select. By default, it will be the current one. Cannot be paired with id argument.

Schema:

{
  "mode": "data",
  "type": "azurerm_region",
  "name": "region",
  "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
  "instances": [
    {
      "schema_version": 0,
      "attributes": {
        "id": "/subscriptions/xxx-xxx-xxx-xxx-xxx/region/northeurope",
        "region_id": "northeurope",
        "region_name": "North Europe",
        "region_type": "Physical",
        "zone_ids": ["1", "2", "3"],
        "zone_names": ["northeurope-az1", "northeurope-az2", "northeurope-az3"],
        "zone_mapping": [
          {
            "id": "1",
            "name": "northeurope-az1"
          },
          {
            "id": "2",
            "name": "northeurope-az3"
          },
          {
            "id": "3",
            "name": "northeurope-az2"
          }
        ]
      },
      "sensitive_attributes": []
    }
  ]
}

@tombuildsstuff
Copy link
Member

@clemlesne FWIW the name for this should be location and not region for consistency across the provider - whilst Azure uses Region in the Portal - Location is used throughout the API and depending on the API this can comprise both an Azure Region, Extended Locations and other off-Azure locations (e.g. Arc/Hybrid - I vaguely recall some of the AWS related resources in Azure using a field named location to handle AWS regions too, but I maybe misremembering?)

@theonlyames
Copy link

While this isn't strictly related to availability zones, now that there is an azurerm_location data source would it make sense to include the paired region/location for a given location in the azurerm_location data source as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants