class_docstr: Node Provider for Azure
  
  This provider assumes Azure credentials are set by running ``az login``
  and the default subscription is configured through ``az account``
  or set in the ``provider`` field of the autoscaler configuration.
  
  Nodes may be in one of three states: {pending, running, terminated}. Nodes
  appear immediately once started by ``create_node``, and transition
  immediately to terminated when ``terminate_node`` is called.
class_docstr_tok: ["Node","Provider","for","Azure","This","provider","assumes","Azure","credentials","are","set","by","running","``","az","login","``","and","the","default","subscription","is","configured","through","``","az","account","``","or","set","in","the","``","provider","``","field","of","the","autoscaler","configuration",".","Nodes","may","be","in","one","of","three","states",":","{","pending",",","running",",","terminated","}",".","Nodes","appear","immediately","once","started","by","``","create_node","``",",","and","transition","immediately","to","terminated","when","``","terminate_node","``","is","called","."]
docstr: Terminates the specified node. This will delete the VM and
  associated resources (NIC, IP, Storage) for the specified node.
docstr_tok: ["Terminates","the","specified","node",".","This","will","delete","the","VM","and","associated","resources","(","NIC",",","IP",",","Storage",")","for","the","specified","node","."]
code: def terminate_node(self, node_id):
      """Terminates the specified node. This will delete the VM and
      associated resources (NIC, IP, Storage) for the specified node."""
  
      resource_group = self.provider_config["resource_group"]
      try:
          # get metadata for node
          metadata = self._get_node(node_id)
      except KeyError:
          # node no longer exists
          return
  
      if self.cache_stopped_nodes:
          try:
              # stop machine and leave all resources
              logger.info(
                  f"Stopping instance {node_id}"
                  "(to fully terminate instead, "
                  "set `cache_stopped_nodes: False` "
                  "under `provider` in the cluster configuration)"
              )
              stop = get_azure_sdk_function(
                  client=self.compute_client.virtual_machines,
                  function_name="deallocate",
              )
              stop(resource_group_name=resource_group, vm_name=node_id)
          except Exception as e:
              logger.warning("Failed to stop VM: {}".format(e))
      else:
          vm = self.compute_client.virtual_machines.get(
              resource_group_name=resource_group, vm_name=node_id
          )
          disks = {d.name for d in vm.storage_profile.data_disks}
          disks.add(vm.storage_profile.os_disk.name)
  
          try:
              # delete machine, must wait for this to complete
              delete = get_azure_sdk_function(
                  client=self.compute_client.virtual_machines,
                  function_name="delete",
              )
              delete(
                  resource_group_name=resource_group, vm_name=node_id
              )
          except Exception as e:
              logger.warning("Failed to delete VM: {}".format(e))
  
          try:
              # delete nic
              delete = get_azure_sdk_function(
                  client=self.network_client.network_interfaces,
                  function_name="delete",
              )
              delete(
                  resource_group_name=resource_group,
                  network_interface_name=metadata["nic_name"],
              )
          except Exception as e:
              logger.warning("Failed to delete nic: {}".format(e))
  
          # delete ip address
          if "public_ip_name" in metadata:
              try:
                  delete = get_azure_sdk_function(
                      client=self.network_client.public_ip_addresses,
                      function_name="delete",
                  )
                  delete(
                      resource_group_name=resource_group,
                      public_ip_address_name=metadata["public_ip_name"],
                  )
              except Exception as e:
                  logger.warning(
                      "Failed to delete public ip: {}".format(e)
                  )
  
          # delete disks
          for disk in disks:
              try:
                  delete = get_azure_sdk_function(
                      client=self.compute_client.disks,
                      function_name="delete",
                  )
                  delete(
                      resource_group_name=resource_group, disk_name=disk
                  )
              except Exception as e:
                  logger.warning("Failed to delete disk: {}".format(e))
  
imports: import json
  import logging
  from pathlib import Path
  from threading import RLock
  from uuid import uuid4
  from azure.identity import DefaultAzureCredential
  from azure.mgmt.compute import ComputeManagementClient
  from azure.mgmt.network import NetworkManagementClient
  from azure.mgmt.resource import ResourceManagementClient
  from azure.mgmt.resource.resources.models import DeploymentMode
  from ray.autoscaler._private._azure.config import bootstrap_azure, get_azure_sdk_function
  from ray.autoscaler.node_provider import NodeProvider
  from ray.autoscaler.tags import TAG_RAY_CLUSTER_NAME, TAG_RAY_LAUNCH_CONFIG, TAG_RAY_NODE_KIND, TAG_RAY_NODE_NAME, TAG_RAY_USER_NODE_TYPE
label_desc: Use image node_id 14 for calling the AzureNodeProvider obj's underlying member method code with example usage: obj.terminate_node(node_id) without return types