Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run Azure CLI commands using python?

I want to use Azure CLI to get the list of all the VMs in my resource group. But I want to implement the same using a python script.

For example, I will use the following command in Azure CLI to list the VMs in my resource group:

" az vm list -g MyResourceGroup "

But, I want the python script to do the same, where I just have to incorporate the CLI command in the python program.

like image 837
Software Fan Avatar asked Jul 26 '18 19:07

Software Fan


4 Answers

My understanding is that the current recommendation is to use the management libraries for this.

The SDK's management (or "management plane") libraries, the names of which all begin with azure-mgmt-, help you create, provision and otherwise manage Azure resources from Python scripts. All Azure services have corresponding management libraries.
With the management libraries, you can write configuration and deployment scripts to perform the same tasks that you can through the Azure portal or the Azure CLI.

More info here: Provision and manage Azure resources with management libraries

like image 176
genegc Avatar answered Sep 24 '22 13:09

genegc


I have been implementing this over the last couple days. The method that @cbehrenberg provides is mostly what I used, but I found that you can do it without using a temporary file. Instead catch the output directly from the azure client. Thought it might be useful.

from azure.cli.core import get_default_cli

def az_cli (args_str):
    args = args_str.split()
    cli = get_default_cli()
    cli.invoke(args)
    if cli.result.result:
        return cli.result.result
    elif cli.result.error:
        raise cli.result.error
    return True

Then invoked the same way:

from azhelper import az_cli

response = az_cli("vm list")
print("vm's: %s" % (response))
like image 20
joek575 Avatar answered Oct 09 '22 12:10

joek575


How to run Azure CLI commands using python?

According to this file. we could invoke the Azure CLI with following way:

from azure.cli.core import get_default_cli
get_default_cli().invoke(['vm', 'list', '-g', 'groupname'])

Note : If you get No module named 'azure.cli.command_modules' error, please install azure-cli

enter image description here

like image 10
Tom Sun - MSFT Avatar answered Oct 09 '22 13:10

Tom Sun - MSFT


Using the subprocess solution is problematic as subprocess doesn't check the PATH where Azure CLI is found e.g. on Windows. To use "cmd -c" would be a Windows-specific solution and needs a fork if/else for additional Linux support.

@tom-sun's answer is almost correct, as you can reuse the Azure CLI python modules, as the CLI is also written in Python. Problem is, that the return of the .invoke() instruction is always returning the error code. To get the full body response, you must pass a file like object on the argument list of the underlying Knack Code to get the response. By default, this redirects to StdOut, that is why you can see it e.g. in your terminal but you always get a zero for success.

I wrote a little helper function that accepts the Azure CLI instructions in one string (I don't like many arguments as list, it doesn't read nicely - but that is just a personal preference, don't blame me). It uses a temporary file as output target and then it is read back in memory - this is required afaik from the underlying Knack CLI code; by default StdOut is the standard pipe.

It requires you to have azure-cli installed for Python: pip install azure-cli

File azhelper.py:

from azure.cli.core import get_default_cli
import tempfile

def az_cli (args_str):
    temp = tempfile.TemporaryFile()
    args = args_str.split()
    code = get_default_cli().invoke(args, None, temp)
    temp.seek(0)
    data = temp.read().strip()
    temp.close()
    return [code, data]

You can then invoke like this:

from azhelper import *

code, response = az_cli("vm list")
print("vm's: %s" % (response))

Of course you need to be logged in, see @4c74356b41 answer.

If somebody finds a better way to deal with the response instead with a temporary file, this would be much appreciated! I tried with an in memory StringIO object but this somehow doesn't comply with the underlying Knack CLI code.

like image 7
cbehrenberg Avatar answered Oct 09 '22 11:10

cbehrenberg