Azure CLI Installation and Configuration

The Azure CLI is the official command-line tool for managing Microsoft Azure resources from Linux, enabling automation of VM provisioning, storage management, networking, and subscription administration. This guide covers installing the Azure CLI on Linux, authenticating to your Azure subscription, and using it to manage resources and build automation scripts.

Prerequisites

  • Ubuntu/Debian or CentOS/Rocky Linux
  • An active Microsoft Azure account
  • Sudo access on the server

Installing the Azure CLI

Ubuntu/Debian

# Install dependencies
sudo apt-get update
sudo apt-get install -y ca-certificates curl apt-transport-https lsb-release gnupg

# Add the Microsoft signing key
curl -sLS https://packages.microsoft.com/keys/microsoft.asc | \
  gpg --dearmor | \
  sudo tee /etc/apt/keyrings/microsoft.gpg > /dev/null
sudo chmod go+r /etc/apt/keyrings/microsoft.gpg

# Add the Azure CLI repository
AZ_DIST=$(lsb_release -cs)
echo "Types: deb
URIs: https://packages.microsoft.com/repos/azure-cli/
Suites: ${AZ_DIST}
Components: main
Architectures: $(dpkg --print-architecture)
Signed-by: /etc/apt/keyrings/microsoft.gpg" | \
  sudo tee /etc/apt/sources.list.d/azure-cli.sources

sudo apt-get update && sudo apt-get install -y azure-cli

CentOS/Rocky Linux

sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc

sudo tee /etc/yum.repos.d/azure-cli.repo << 'EOF'
[azure-cli]
name=Azure CLI
baseurl=https://packages.microsoft.com/yumrepos/azure-cli
enabled=1
gpgcheck=1
gpgkey=https://packages.microsoft.com/keys/microsoft.asc
EOF

sudo dnf install -y azure-cli

Verify Installation

az version
# {
#   "azure-cli": "2.x.x",
#   "azure-cli-core": "2.x.x",
#   ...
# }

Authentication and Login

Interactive Login

az login
# Opens browser or shows a device code for headless servers

For servers without browser access:

az login --use-device-code
# Go to https://microsoft.com/devicelogin and enter the code

Service Principal Login (for automation)

# Create a service principal
az ad sp create-for-rbac \
  --name "my-automation-sp" \
  --role contributor \
  --scopes /subscriptions/YOUR_SUBSCRIPTION_ID

# Login with service principal
az login \
  --service-principal \
  --username APP_ID \
  --password PASSWORD \
  --tenant TENANT_ID

Environment Variable Authentication

export AZURE_CLIENT_ID="your-app-id"
export AZURE_CLIENT_SECRET="your-password"
export AZURE_TENANT_ID="your-tenant-id"
export AZURE_SUBSCRIPTION_ID="your-subscription-id"

Subscription Management

# List all subscriptions
az account list --output table

# Show current active subscription
az account show

# Switch to a different subscription
az account set --subscription "My Production Subscription"

# Set subscription by ID
az account set --subscription 00000000-0000-0000-0000-000000000000

Resource Groups

Resource groups organize Azure resources by lifecycle and region.

# List all resource groups
az group list --output table

# Create a resource group
az group create \
  --name my-resource-group \
  --location eastus

# Show details of a resource group
az group show --name my-resource-group

# List resources within a group
az resource list --resource-group my-resource-group --output table

# Delete a resource group (and all resources within it)
az group delete --name my-resource-group --yes --no-wait

Managing Virtual Machines

# List all VMs
az vm list --output table

# Create a VM
az vm create \
  --resource-group my-resource-group \
  --name my-vm \
  --image Ubuntu2204 \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --output json

# Start and stop VMs
az vm start --resource-group my-resource-group --name my-vm
az vm stop --resource-group my-resource-group --name my-vm
az vm deallocate --resource-group my-resource-group --name my-vm

# Get VM's public IP address
az vm show \
  --resource-group my-resource-group \
  --name my-vm \
  --show-details \
  --query publicIps \
  --output tsv

# Open a port in the Network Security Group
az vm open-port \
  --resource-group my-resource-group \
  --name my-vm \
  --port 80

# Resize a VM
az vm resize \
  --resource-group my-resource-group \
  --name my-vm \
  --size Standard_B4ms

# List available VM sizes in a region
az vm list-sizes --location eastus --output table

Azure Storage Operations

# Create a storage account
az storage account create \
  --name mystorageaccount \
  --resource-group my-resource-group \
  --location eastus \
  --sku Standard_LRS

# Get storage account keys
az storage account keys list \
  --account-name mystorageaccount \
  --resource-group my-resource-group

# Create a blob container
az storage container create \
  --name my-container \
  --account-name mystorageaccount

# Upload a file to blob storage
az storage blob upload \
  --account-name mystorageaccount \
  --container-name my-container \
  --name backup.tar.gz \
  --file /var/backups/backup.tar.gz

# List blobs in a container
az storage blob list \
  --account-name mystorageaccount \
  --container-name my-container \
  --output table

# Download a blob
az storage blob download \
  --account-name mystorageaccount \
  --container-name my-container \
  --name backup.tar.gz \
  --file /tmp/backup.tar.gz

Scripting and Automation

Use --query with JMESPath expressions to filter output in scripts:

# Get only running VMs
az vm list \
  --query "[?powerState=='VM running'].{Name:name, RG:resourceGroup, IP:publicIps}" \
  --show-details \
  --output table

# Script to stop all VMs in a resource group
#!/bin/bash
RG="my-resource-group"
for vm in $(az vm list -g $RG --query "[].name" -o tsv); do
  echo "Stopping $vm..."
  az vm deallocate -g $RG -n "$vm" --no-wait
done

# Use --output tsv for clean script parsing
SUBSCRIPTION=$(az account show --query id --output tsv)
echo "Current subscription: $SUBSCRIPTION"

Troubleshooting

"Please run 'az login'"

az login
# Check login status
az account show

Expired token / authentication errors

az account clear
az login

"Resource not found"

# Verify the resource group and subscription
az account show
az group list --output table

# Ensure the correct subscription is active
az account set --subscription "Correct Subscription Name"

Slow CLI performance

# Disable telemetry if needed
az config set core.collect_telemetry=false

# Update the CLI
az upgrade

Extension errors

# List installed extensions
az extension list --output table

# Update all extensions
az extension update --name <extension-name>

Conclusion

The Azure CLI provides a consistent and scriptable interface for managing all Microsoft Azure resources from Linux. With service principal authentication and JMESPath query filtering, you can build reliable automation workflows for VM management, storage operations, and infrastructure provisioning across multiple subscriptions.