1

I'm trying to get a list of private IP addresses for all VMs in a Scale Set (none of the VMs deliberately has any public IP addresses). I've found how to get this from az cli as follows:

az vmss nic list -g ResourceGroup --vmss-name ScaleSetName --query [].{ip:ipConfigurations[0].privateIpAddress} -o tsv

However I'm unable to get the same output using Python SDK. I am using the following basic code:

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.compute import ComputeManagementClient

credentials = ServicePrincipalCredentials(client_id = CLIENT, secret = KEY, tenant = TENANT)

compute_client = ComputeManagementClient(credentials, SUBSCRIPTION)

vmss = compute_client.virtual_machine_scale_sets.get(RG, SC)
print(vmss.virtual_machine_profile.network_profile.network_interface_configurations[0].ip_configurations[0])

Is this the right place in the SDK object model to look for them? From what I understand, the network properties should be at the Scale Set level, and that's the only place in the API where I see anything network-related. However, I only see 'private IP version' in the subsequent properties, and since there are no public IPs, that portion of the properties is blank.

VS_FF
  • 2,353
  • 3
  • 16
  • 34

2 Answers2

3

Unfortunately, I'm afraid you cannot get the private IP of virtual machine scale set instances. The network interfaces of virtual machine scale sets are not the resources in Azure and you cannot get them. Currently, Azure python SDK does not support get the VMSS private IPs through the python SDK.

You can try to use the REST API to achieve the purpose and get the REST API via the CLI command debug like this:

az vmss nic list -g ResourceGroup --vmss-name ScaleSetName --query [].{ip:ipConfigurations[0].privateIpAddress} -o tsv --debug

It will show the progress and the REST API:

enter image description here

Charles Xu
  • 29,862
  • 2
  • 22
  • 39
  • Yes, as noted in the question, I'm aware of the az cli command. For now I'm getting by with calling that command as an external process from python. But (1) it's very cumbersome and (2) it requires az cli to be authenticated first on the given machine – VS_FF Jan 07 '20 at 09:56
  • @VS_FF I do not mean use the CLI, I mean to use the REST API in your Python code. – Charles Xu Jan 08 '20 at 01:16
  • @VS_FF What is the situation now? Do you solve the problem with my answer? Or more help? – Charles Xu Jan 09 '20 at 02:57
  • I can't use REST as per your suggestion, for internal reasons. As I mentioned, I continue using the AZ command by spawning a process from inside python. This approach works better for my purposes than REST. Of course would have been better if the SDK actually supported such simple functionality... – VS_FF Jan 09 '20 at 09:43
  • @VS_FF I'm afraid you only can use the CLI or REST API in your python code currently. Maybe Azure SDK will support it in the future as we expected. In addition, if you do not mind, please accept the answer when it's helpful. – Charles Xu Jan 09 '20 at 09:47
  • @VS_FF I think my answer if helpful and explain the situation for your question currently. So if you do not have other ideas, you should accept it. – Charles Xu Jan 21 '20 at 07:38
  • Was waiting for other proper pythonic ideas, but clearly none is coming, so let's consider this the accepted answer.. – VS_FF Jan 21 '20 at 10:19
3

If you're already using the Python azure sdk, you can pull the Bearer token from the azure.identity credential which makes this REST API call much easier to do:

credentials = ClientSecretCredential(
    client_id=os.environ['AZURE_CLIENT_ID'],
    client_secret=os.environ['AZURE_CLIENT_SECRET'],
    tenant_id=os.environ['AZURE_TENANT_ID']
)  

# Grab the bearer token from the existing azure credential,
# and use it to AUTH the REST api call:
rest_token = credentials._request_token('https://management.core.windows.net//.default')
vmss_nic_json = vmss_rest_api_list_nics(rest_token.token, subscription_id, resource_group, vmss_name)

# REST API call:
def vmss_rest_api_list_nics(token, subscription_id, resource_group, vmss_name, api_version='2018-10-01'):
    
    url = f"https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/microsoft.Compute/virtualMachineScaleSets/{vmss_name}/networkInterfaces"
    params = {'api-version': api_version}
    request = requests.Request('GET', url, params=params)
    prepped = request.prepare()
    prepped.headers['Authorization'] = f'Bearer {token}'

    with requests.Session() as session:
        response = session.send(prepped )

        if( response.status_code == 200 ):
            return json.loads(response.text)
        else:
            logger.error(f"Failed to communicate with api service: HTTP {response.status_code} - {response.text}")
            return None
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61