Nigel Sheridan-Smith
Nigel Sheridan-Smith

Reputation: 775

Obtaining Azure VM scale set private IP addresses through Azure REST API

Can you get a list of Azure VM scale set instance private IP addresses through the Azure REST API?

It seems that Microsoft does not publish the VMSS IP configuration objects under the normal methods for retrieving a list of "ipConfigurations".

Here are some relevant API doc pages:

https://learn.microsoft.com/en-us/rest/api/compute/virtualmachinescalesets/listall https://learn.microsoft.com/en-us/rest/api/compute/virtualmachinescalesets/get https://learn.microsoft.com/en-us/rest/api/compute/virtualmachines/listall

In particular, this one only gives you the IP configuration of VMs, not VMSSes: https://learn.microsoft.com/en-us/rest/api/virtualnetwork/networkinterfaces/listall

Upvotes: 1

Views: 3238

Answers (3)

Alexander Komlik
Alexander Komlik

Reputation: 31

you can get VM hostnames that will resolve to IPs thanks to Azure DNS

$ curl -H "Authorization: Bearer $JWT_TOCKEN"  -sf https://management.azure.com/subscriptions/${subscription_id}/resourceGroups/${resourc_group}/providers/Microsoft.Compute/virtualMachineScaleSets/${scale_set}/virtualMachines?api-version=2018-10-01 |  jq '.value[].properties.osProfile.computerName'
"influx-meta000000"
"influx-meta000001"

$ getent hosts influx-meta000001
10.120.10.7     influx-meta000001.l55qt5nuiezudgvyxzyvtbihmf.gx.internal.cloudapp.net

Upvotes: 0

Bill Pratt
Bill Pratt

Reputation: 21

Looking at the Azure CLI, there is az vmss nic list which returns all network interfaces in a virtual machine scale set. Looking at the results, there is

{
  "dnsSettings": {
    ...
  },
  "ipConfigurations": [
    {
      privateIpAddress: "..."
    }
   ]
}

You can use the --query syntax to get all private IPs.

az vmss nic list -g <resource_group> --vmss-name <vmss_name> --query [].{ip:ipConfigurations[0].privateIpAddress} -o tsv

Upvotes: 2

Nigel Sheridan-Smith
Nigel Sheridan-Smith

Reputation: 775

Here's how to get a list of private IP addresses for VMs and VMSS instances through Ruby:

require 'openssl'

require 'azure_mgmt_network'
require 'azure_mgmt_compute'
require 'awesome_print'

options = {
    tenant_id: '<tenant_id>',
    client_id: '<client_id>',
    client_secret: '<client_secret>',
    subscription_id: '<subscription_id>'
}

def net_interface_to_ip_mapping(client)
  network_interfaces = client.network_interfaces.list_all
  pairs = network_interfaces.collect { |ni| [ni.id.split('/').last, ni.ip_configurations.collect { |ip| ip.private_ipaddress }.flatten.compact[0] ] }
  [network_interfaces, pairs]
end

def net_interface_to_vm(ni)
  interface_vm_set = ni.collect { |prof| [prof.id, prof.virtual_machine, prof.ip_configurations.collect(&:id)] }
  ipconf_to_host = interface_vm_set.collect { |x| [x[2][0], x[1]&.id&.split('/')&.last] }.to_h
  conf_ip_map = ni.collect(&:ip_configurations).flatten.compact.collect { |ipconf| [ipconf&.id, ipconf&.private_ipaddress] }.to_h
  [ipconf_to_host, conf_ip_map]
end

puts "*** Network Interfaces"
puts
client = Azure::Network::Profiles::Latest::Mgmt::Client.new(options)
ni, pairs = net_interface_to_ip_mapping(client)
pairs.to_h.each do |ni, ip|
  puts "  #{ni}: #{ip}"
end

puts
puts "*** Virtual Machines"
puts

ipconf_to_host, conf_ip_map = net_interface_to_vm(ni)
ipconf_to_host.each do |ipconf, host|
  ni_name = ipconf.split('/')[-3]
  puts "  #{host || '#  ' + ni_name} - #{conf_ip_map[ipconf]}"
end

puts
puts "*** Virtual Machine Scale Sets"
puts

vns = client.virtual_networks.list_all
vns.each do |vn|
  resource_group = vn.id.split('/')[4]
  puts
  vn_details = client.virtual_networks.get(resource_group, vn.name,  expand: 'subnets/ipConfigurations')
  ip_configs = vn_details&.subnets&.collect { |subnet| subnet&.ip_configurations&.collect { |ip| [ip&.id, ip&.name, ip&.private_ipaddress] } }.compact
  vmss_ipconf = ip_configs.collect { |subnet| subnet.select { |ipconf| ipconf[0].include?('/virtualMachineScaleSets/') } }
  vmss_ipconf.each do |subnet|
    subnet.each do |ipconf|
      vmss_name = ipconf[0].split('/')[8]
      vmss_instance = ipconf[0].split('/')[10]
      puts "#{vmss_name} ##{vmss_instance} - #{ipconf[2]}"
    end
  end
end

Upvotes: 2

Related Questions