Az.Cli
is an easy-to-use interface that lets developers and administrators query Azure using Python.
If you are already familiar with the Azure CLI you should feel right at home using the Az.Cli
Python package API.
The interface is providing a way to interact with Azure using the well-known Azure CLI command syntax.
Every command that is available in the Azure CLI can be executed using the function az("<sub command>")
.
The function enables Azure developers and administrators to run shell like commands like az group list
inside of Python like az("group list")
.
Why?
I encountered numerous projects where Azure developers and administrators created sophisticated shell scripts that leverage the idempotent functionality of the Azure CLI to get their work done.
While bash scripts are great to get things done quickly and the WSL allows Windows users to run and develop shell scripts as well, I always disliked the syntax and unnecessary complication of bash scripting. Including user input, input validation, loops, property access (mostly done using jq
), as well as logging and error handling.
At mature teams, we can find the implementation of shell style guides, and the implementation of tools for linting like shellcheck, as well as testing to deal with the increasing complexity of the Infrastructure as Code automation over time.
I like to implement these tools in the early stages of Cloud adoption to get things done. However, I found that they leave a lot of legacy behind if the complexity is not fought. Poorly written shell scripts create a high degree of maintenance work and toil in large-scale environments, in my experience. If not worked on continuously the increasing complexity makes these shell scripts hard to maintain. Onboarding new users to the codebase is often a mess and result in a lot of frustration.
The Az.Cli
tries to address this problem by providing a simple solution to this mess, as it allows the refactoring of existing shell scripts from the Azure CLI to an easy-to-read, easy-to-maintain Python implementation.
Moving to Python harnesses the power of a fully-fledged object-oriented scripting language with a huge open-source community and wide adoption while sticking to a well-known syntax, that is enabling teams to onboard new team members quicker, as well as increase the maintainability through native Python capabilities like logging, tracing, debugging and unit testing.
As the Az.Cli
relies on the official Python libraries of the Azure CLI it is fully compatible and stays up-to-date.
How to start
Visit pypi.org/project/az.cli/ and install the package using pip. A getting started guide is provided in the pypi description or visit github.com/MarkWarneke/Az.Cli for more information and help.
Install the package
pip install az.cli
After installing the package log in using az login
or sign in using a service principal.
Under the hood the package uses the ~/.azure folder to persist and retrieve config.
The az
function returns a named tuple that allows you to retrieve the results easily.
AzResult = namedtuple('AzResult', ['exit_code', 'result_dict', 'log'])
- The
error_code
where0 == success
. - The
result_dict
containing a python dictionary on a successful return. - On failure (
error_code
> 0) a log message is available in thelog
property as a string.
Example
The usage of the packe is straight forward, after installing and importing the package.
from az.cli import az
# AzResult = namedtuple('AzResult', ['exit_code', 'result_dict', 'log'])
exit_code, result_dict, logs = az("group list")
# On 0 (SUCCESS) print result_dict, otherwise get info from `logs`
if exit_code == 0:
print (result_dict)
else:
print(logs)
… or simply
az("group list")[0] # error code
az("group list")[1] # result
az("group list")[2] # log messages on failure
Visit pypi.org/project/az.cli/ now and install the package to try it yourself!
Programmatically Setting The Azure Config
To change the Azure context, the “session” in which you are logged in, the package relies on the stored credentials inside the ~/.azure
folder by default.
This typically limits the context in which an automation script can execute to the saved context.
Querying multiple tenants or with different users requires you to sign-in multiple times and switch between the contexts.
To change the credentials a change to the environment variable AZURE_CONFIG_DIR
will point to a new context.
This can easily be done in Python using the os.enviorn
interface.
To try this in the shell version of the Azure CLI sign in with different service principals and copy the ~/.azure
folder multiple times.
One way to validate this functionality is to perpend AZURE_CONFIG_DIR
in front of an Azure CLI command.
az login
mv ~/.azure/* ~/.azure-mw
az login --service-principal -u $id -p $p -t $t
# Validate that it works
AZURE_CONFIG_DIR=.azure az group list
AZURE_CONFIG_DIR=.azure-mw az group list
In a Python script the environment variable can be set using:
os.environ['AZURE_CONFIG_DIR'] = "<OTHER AZURE CONFIG DIR>"
Changing the AZURE_CONFIG_DIR
environment variables is described in the docs to the Azure CLI environment variables.
To demonstrate how to change the environment variable programmatically a small example:
from az.cli import az
import os
exit_code, result_dict, logs = az("group list")
print (result_dict)
# [{'id': '/subscriptions/...', 'location': 'westeurope', 'name': 'test1']
# Change the environment variable
os.environ['AZURE_CONFIG_DIR'] = '/Users/mark/.azure_mw'
exit_code, result_dict, logs = az("group list")
print (result_dict)
# [{'id': '/subscriptions/...', 'location': 'westeurope', 'name': 'test2']
Interactively Querying Azure Using Python
You can also use the package to interactively query Azure resources using Python.
Just start a new interactive Python prompt $ python3
from az.cli import az
# list return tuple (exit_code, result_dict, log)
az("group list")
# on Success, the `error_code` is 0 and the result_dict contains the output
az("group list")[0]
# print the returned object
az("group list")[1]
# enumerate the id of the first element in dictionary
az("group list")[1][0]['id']
# On Error, the `error_code` will be != 0 and the log property is returned
az("group show -n does-not-exsist")
az("group show -n does-not-exsist")[0] # returns 3
# print the error messagelog
az("group show -n does-not-exsist")[2]
How it works
The package is an easy-to-use abstraction on top of the official Microsoft Azure CLI.
The official azure.cli.core library is simply wrapped in a function to execute Azure CLI commands using Python3.
The package provides a function az
, that is instantiating the library class AzCLI
.
It exposes the function to execute az
which takes the sub command
of Azure CLI shell command as a string input.
The invocation of this method returns the results in a structured manner.
Generating a namedtuple where namedtuple('AzResult', ['exit_code', 'result_dict', 'log'])
.
It has thus a similar API and usage to the shell version of the Azure CLI, but commands can be executed within Python, leveraging Pythons full potential.
The package uses the stored credentials in ~/.azure folder to retrieve the current context and log-in information. This is particularly useful if you want to programmatically set the current Azure Configuration, for instance when dealing with multiple Azure tenants.
Visit pypi.org/project/az.cli/ now and install the package to try it yourself!