How to run Azure CLI commands using python?

2019-02-21 01:19发布

问题:

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.

回答1:

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



回答2:

since you still didnt delete this I assume you still looking for a way.

from subprocess import call   
call(["az", "vm", "list", "-g", "rgName"])

you will also need to silently auth first with something like:

az login --service-principal -u http://sample-cli-login -p Test1234 --tenant 54826b22-38d6-4fb2-bad9-b7b93a3e9c5a


回答3:

I think you can use the subprocess and call the az cli to get the output instead using get_default_cli. Reference Git Repo

import subprocess
import json

process = subprocess.Popen(['az','network', 'ddos-protection', 'list'], stdout=subprocess.PIPE)
out, err = process.communicate()
d = json.loads(out)
print(d)


回答4:

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.



回答5:

Use subprocess.run instead of using subprocess.Popen

It will by default cause python script to wait until the program run from subprocess (in this case azure cli command) is completed.

For example, let's create an Azure AD application.

import subprocess
import json

# create command you want to run on az cli as a string
create_app_command = "az ad sp create-for-rbac --skip-assignment --years 20 --name dummy_app"

# use 'shell = True' as Azure CLI installed on system is accessible from native shell
# using 'subprocess.PIPE' will return stderr and stdout to create_app object
create_app = subprocess.run(create_app_command, shell = True, stdout=sbuprocess.PIPE, stderr = sbuprocess.PIPE)

# reading output and error
create_app_stdout =  create_app.stdout.decode("utf-8")
create_app_stderr = create_app.stderr.decode("utf-8")

# now you can log error to a file 'logging.error(create_app_stderr)

# you can use stdout for further logic in code
# let's get you need to get appID and password for authentication somewhere later in code
ad_app_details = json.loads(create_app_stdout)
ad_app_appId = ad_app_details['appId']
ad_app_password = ad_app_details['password']

For more information on using subprocess module see this link