Exploración de recursos de Azure con el gráfico de recursos

Azure Resource Graph le ayuda a explorar y detectar los recursos de Azure rápidamente y a escala. Diseñado para respuestas rápidas, es una excelente manera de aprender sobre el entorno y también sobre las propiedades existentes en los recursos de Azure.

Nota

En función de la tabla de Resource Graph, las propiedades coincidirán con el uso de mayúsculas y minúsculas, tal como se muestra en Azure Portal; o se convertirán en minúsculas. Por ejemplo, el nombre de un grupo de recursos al consultar la tabla resourceContainers coincidirá con el portal, pero la propiedad resourceGroup de los recursos de la tabla resources estará en minúsculas. Esto puede provocar resultados inesperados y se puede tener en cuenta en las consultas mediante operadores de comparación que no distinguen mayúsculas de minúsculas, como =~ en lugar de == y convertir propiedades en minúsculas en combinaciones con la tolower() función .

Exploración de máquinas virtuales

Un recurso común en Azure es una máquina virtual. Como tipo de recurso, las máquinas virtuales tienen muchas propiedades que se pueden consultar. Cada propiedad ofrece una opción para filtrar o buscar exactamente el recurso que está buscando.

Detección de la máquina virtual

Comencemos con una consulta simple para obtener una única máquina virtual de nuestro entorno y ver las propiedades devueltas.

Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| limit 1
az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | limit 1"
(Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | limit 1").Data | ConvertTo-Json -Depth 100

Nota

El cmdlet Search-AzGraph de Azure PowerShell devuelve un objeto PSResourceGraphResponse de forma predeterminada. Para que la salida sea parecida a lo que devuelve la CLI de Azure, se usa el cmdlet ConvertTo-Json en la propiedad Data. El valor predeterminado de Depth es 2. Si se establece en 100 Se deberían convertir todos los niveles devueltos.

Los resultados de JSON tienen una estructura similar a la del ejemplo siguiente:

[
  {
    "id": "/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/ContosoVM1",
    "kind": "",
    "location": "westus2",
    "managedBy": "",
    "name": "ContosoVM1",
    "plan": {},
    "properties": {
      "hardwareProfile": {
        "vmSize": "Standard_B2s"
      },
      "networkProfile": {
        "networkInterfaces": [
          {
            "id": "/subscriptions/<subscriptionId>/MyResourceGroup/providers/Microsoft.Network/networkInterfaces/contosovm1535",
            "resourceGroup": "MyResourceGroup"
          }
        ]
      },
      "osProfile": {
        "adminUsername": "localAdmin",
        "computerName": "ContosoVM1",
        "secrets": [],
        "windowsConfiguration": {
          "enableAutomaticUpdates": true,
          "provisionVMAgent": true
        }
      },
      "provisioningState": "Succeeded",
      "storageProfile": {
        "dataDisks": [],
        "imageReference": {
          "offer": "WindowsServer",
          "publisher": "MicrosoftWindowsServer",
          "sku": "2016-Datacenter",
          "version": "latest"
        },
        "osDisk": {
          "caching": "ReadWrite",
          "createOption": "FromImage",
          "diskSizeGB": 127,
          "managedDisk": {
            "id": "/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/disks/ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166",
            "resourceGroup": "MyResourceGroup",
            "storageAccountType": "Premium_LRS"
          },
          "name": "ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166",
          "osType": "Windows"
        }
      },
      "vmId": "bbb9b451-6dc7-4117-bec5-c971eb1118c6"
    },
    "resourceGroup": "MyResourceGroup",
    "sku": {},
    "subscriptionId": "<subscriptionId>",
    "tags": {},
    "type": "microsoft.compute/virtualmachines"
  }
]

Las propiedades nos proporcionan información adicional sobre el propio recurso de máquina virtual. Estas propiedades incluyen: sistema operativo, discos, etiquetas, así como el grupo de recursos y la suscripción de los que es miembro.

Máquinas virtuales por ubicación

Tomando lo que hemos aprendido sobre el recurso de máquinas virtuales, vamos a usar la propiedad location para contar todas las máquinas virtuales por ubicación. Para actualizar la consulta, se quita el límite y se resume el recuento de valores de ubicación.

Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| summarize count() by location
az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | summarize count() by location"
(Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | summarize count() by location").Data | ConvertTo-Json

Los resultados de JSON tienen una estructura similar a la del ejemplo siguiente:

[
  {
    "count_": 386,
    "location": "eastus"
  },
  {
    "count_": 215,
    "location": "southcentralus"
  },
  {
    "count_": 59,
    "location": "westus"
  }
]

Ahora podemos ver cuántas máquinas virtuales tenemos en cada región de Azure.

Máquinas virtuales por SKU

Volviendo a las propiedades originales de la máquina virtual, vamos a intentar encontrar todas las máquinas virtuales que tengan un tamaño de SKU de Standard_B2s. El JSON devuelto muestra que se almacena en properties.hardwareprofile.vmsize. Actualizaremos la consulta para buscar todas las máquinas virtuales que coincidan con este tamaño y se devolverá solo el nombre de la máquina virtual y la región.

Resources
| where type =~ 'Microsoft.Compute/virtualMachines' and properties.hardwareProfile.vmSize == 'Standard_B2s'
| project name, resourceGroup
az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' and properties.hardwareProfile.vmSize == 'Standard_B2s' | project name, resourceGroup"
(Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' and properties.hardwareProfile.vmSize == 'Standard_B2s' | project name, resourceGroup").Data | ConvertTo-Json

Máquinas virtuales conectadas a discos administrados premium

Para obtener los detalles de los discos administrados prémium que están conectados a estas máquinas virtuales Standard_B2s, expandimos la consulta para que nos proporcione el identificador de recurso de esos discos administrados.

Resources
| where type =~ 'Microsoft.Compute/virtualmachines' and properties.hardwareProfile.vmSize == 'Standard_B2s'
| extend disk = properties.storageProfile.osDisk.managedDisk
| where disk.storageAccountType == 'Premium_LRS'
| project disk.id
az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualmachines' and properties.hardwareProfile.vmSize == 'Standard_B2s' | extend disk = properties.storageProfile.osDisk.managedDisk | where disk.storageAccountType == 'Premium_LRS' | project disk.id"
(Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualmachines' and properties.hardwareProfile.vmSize == 'Standard_B2s' | extend disk = properties.storageProfile.osDisk.managedDisk | where disk.storageAccountType == 'Premium_LRS' | project disk.id").Data | ConvertTo-Json

El resultado es una lista de identificadores de disco.

Detección de disco administrado

Con el primer registro de la consulta anterior, vamos a explorar las propiedades que existen en el disco administrado que se asoció a la primera máquina virtual. La consulta actualizada utiliza el identificador del disco y cambia el tipo.

Ejemplo de salida de la consulta anterior, por ejemplo:

[
  {
    "disk_id": "/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/disks/ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166"
  }
]
Resources
| where type =~ 'Microsoft.Compute/disks' and id == '/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/disks/ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166'

Antes de ejecutar la consulta, ¿cómo sabíamos que el tipo debería ser Microsoft.Compute/disks? Si se observa el identificador completo, podrá ver /providers/Microsoft.Compute/disks/ como parte de la cadena. Este fragmento de cadena nos da una sugerencia sobre qué tipo buscar. Un método alternativo sería quitar el límite por tipo y en su lugar buscar solo por el campo del identificador. Como el identificador es único, solo se devolverá un registro y la propiedad type que contiene proporciona ese detalle.

Nota

Para que este ejemplo funcione, debe reemplazar el campo del identificador por un resultado de su propio entorno.

az graph query -q "Resources | where type =~ 'Microsoft.Compute/disks' and id == '/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/disks/ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166'"
(Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/disks' and id == '/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/disks/ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166'").Data | ConvertTo-Json

Los resultados de JSON tienen una estructura similar a la del ejemplo siguiente:

[
  {
    "id": "/subscriptions/<subscriptionId>/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/disks/ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166",
    "kind": "",
    "location": "westus2",
    "managedBy": "",
    "name": "ContosoVM1_OsDisk_1_9676b7e1b3c44e2cb672338ebe6f5166",
    "plan": {},
    "properties": {
      "creationData": {
        "createOption": "Empty"
      },
      "diskSizeGB": 127,
      "diskState": "ActiveSAS",
      "provisioningState": "Succeeded",
      "timeCreated": "2018-09-14T12:17:32.2570000Z"
    },
    "resourceGroup": "MyResourceGroup",
    "sku": {
      "name": "Premium_LRS",
      "tier": "Premium"
    },
    "subscriptionId": "<subscriptionId>",
    "tags": {
      "environment": "prod"
    },
    "type": "microsoft.compute/disks"
  }
]

Exploración de máquinas virtuales para buscar direcciones IP públicas

Este conjunto de consultas primero busca y almacena todos los recursos de interfaces de red (NIC) conectados a las máquinas virtuales. Después, las consultas utilizan la lista de NIC para buscar cada uno de los recursos que es una dirección IP pública y almacenar estos valores. Por último, las consultas proporcionan una lista de las direcciones IP públicas.

# Use Resource Graph to get all NICs and store in the 'nics.txt' file
az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | project nic = tostring(properties['networkProfile']['networkInterfaces'][0]['id']) | where isnotempty(nic) | distinct nic | limit 20" --output table | tail -n +3 > nics.txt

# Review the output of the query stored in 'nics.txt'
cat nics.txt
# Use Resource Graph to get all NICs and store in the $nics variable
$nics = (Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | project nic = tostring(properties['networkProfile']['networkInterfaces'][0]['id']) | where isnotempty(nic) | distinct nic | limit 20").Data

# Review the output of the query stored in the variable
$nics.nic

Utilice el archivo (CLI de Azure) o variable (Azure PowerShell) en la siguiente consulta para obtener los detalles de los recursos de interfaz de red relacionados en los que hay una dirección IP pública asociada a la NIC.

# Use Resource Graph with the 'nics.txt' file to get all related public IP addresses and store in 'publicIp.txt' file
az graph query -q="Resources | where type =~ 'Microsoft.Network/networkInterfaces' | where id in ('$(awk -vORS="','" '{print $0}' nics.txt | sed 's/,$//')') | project publicIp = tostring(properties['ipConfigurations'][0]['properties']['publicIPAddress']['id']) | where isnotempty(publicIp) | distinct publicIp" --output table | tail -n +3 > ips.txt

# Review the output of the query stored in 'ips.txt'
cat ips.txt
# Use Resource Graph  with the $nics variable to get all related public IP addresses and store in $ips variable
$ips = (Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Network/networkInterfaces' | where id in ('$($nics.nic -join "','")') | project publicIp = tostring(properties['ipConfigurations'][0]['properties']['publicIPAddress']['id']) | where isnotempty(publicIp) | distinct publicIp").Data

# Review the output of the query stored in the variable
$ips.publicIp

Por último, utilice la lista de recursos de direcciones IP públicas almacenadas el archivo (CLI de Azure) o variable (Azure PowerShell) para obtener la dirección IP pública real y mostrarla.

# Use Resource Graph with the 'ips.txt' file to get the IP address of the public IP address resources
az graph query -q="Resources | where type =~ 'Microsoft.Network/publicIPAddresses' | where id in ('$(awk -vORS="','" '{print $0}' ips.txt | sed 's/,$//')') | project ip = tostring(properties['ipAddress']) | where isnotempty(ip) | distinct ip" --output table
# Use Resource Graph with the $ips variable to get the IP address of the public IP address resources
(Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' | where id in ('$($ips.publicIp -join "','")') | project ip = tostring(properties['ipAddress']) | where isnotempty(ip) | distinct ip").Data | ConvertTo-Json

Para ver cómo llevar a cabo estos pasos en una sola consulta con el operador join, consulte el ejemplo Enumeración de máquinas virtuales con su interfaz de red y dirección IP pública.

Pasos siguientes