Azure
Comprehensive reference for Microsoft Azure cloud services, CLI operations, and resource management.
Azure
Comprehensive reference for Microsoft Azure cloud services, CLI operations, and resource management.
Overview
Microsoft Azure is a cloud computing platform offering infrastructure, platform, and software services. It provides compute, storage, networking, databases, AI, and DevOps tools through a global network of data centres. Azure integrates tightly with Microsoft products and supports hybrid cloud scenarios.
graph TB
subgraph "Azure Resource Hierarchy"
A[Management Groups] --> B[Subscriptions]
B --> C[Resource Groups]
C --> D[Resources]
end
subgraph "Core Services"
E[Compute]
F[Storage]
G[Networking]
H[Identity]
end
D --> E
D --> F
D --> G
D --> H
E --> E1[VMs]
E --> E2[AKS]
E --> E3[App Service]
E --> E4[Functions]
F --> F1[Blob]
F --> F2[Files]
F --> F3[Queue]
F --> F4[Table]
G --> G1[VNet]
G --> G2[NSG]
G --> G3[Load Balancer]
H --> H1[Entra ID]
H --> H2[RBAC]
Azure CLI Essentials
The Azure CLI (az) is the primary command-line tool for managing Azure resources.
Key Concepts
- Subscriptions: Billing and access boundary for Azure resources
- Resource Groups: Logical containers for grouping related resources
- Regions: Geographic locations for resource deployment
- Tags: Key-value pairs for resource organisation and cost tracking
Installation and Authentication
# Install Azure CLI (Ubuntu/Debian)
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# Install Azure CLI (macOS)
brew install azure-cli
# Login interactively
az login
# Login with service principal
az login --service-principal -u <app-id> -p <password> --tenant <tenant-id>
# Login with managed identity (from Azure VM)
az login --identity
# List accounts
az account list --output table
# Set active subscription
az account set --subscription "Subscription Name"
# or by ID
az account set --subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Show current subscription
az account show
Resource Group Management
# Create resource group
az group create --name myResourceGroup --location uksouth
# List resource groups
az group list --output table
# Show resource group details
az group show --name myResourceGroup
# List resources in a group
az resource list --resource-group myResourceGroup --output table
# Delete resource group (and all resources within)
az group delete --name myResourceGroup --yes --no-wait
# Export resource group as ARM template
az group export --name myResourceGroup > template.json
Configuration and Output
# Configure default location
az configure --defaults location=uksouth
# Configure default resource group
az configure --defaults group=myResourceGroup
# Output formats
az vm list --output table # Tabular format
az vm list --output json # JSON format
az vm list --output yaml # YAML format
az vm list --output tsv # Tab-separated values
# Query with JMESPath
az vm list --query "[].{Name:name, RG:resourceGroup}" --output table
# Get specific property
az vm show --name myVM --resource-group myRG --query "hardwareProfile.vmSize" --output tsv
Virtual Machines
Azure Virtual Machines provide on-demand, scalable computing resources.
flowchart LR
A[VM Image] --> B[Virtual Machine]
B --> C[OS Disk]
B --> D[Data Disks]
B --> E[NIC]
E --> F[VNet/Subnet]
E --> G[Public IP]
E --> H[NSG]
Key Concepts
- VM Sizes: Define CPU, memory, storage, and networking capacity
- Images: Base OS and software configuration (marketplace or custom)
- Availability Sets: Ensure VMs are distributed across fault and update domains
- Scale Sets: Automatically scale identical VMs based on demand
Creating Virtual Machines
# Create a basic VM
az vm create \
--resource-group myResourceGroup \
--name myVM \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys \
--size Standard_B2s
# Create VM with specific settings
az vm create \
--resource-group myResourceGroup \
--name myVM \
--image Win2022Datacenter \
--admin-username azureuser \
--admin-password 'SecureP@ssw0rd!' \
--size Standard_D2s_v3 \
--public-ip-sku Standard \
--vnet-name myVNet \
--subnet mySubnet \
--nsg myNSG
# List available VM sizes in a region
az vm list-sizes --location uksouth --output table
# List available images
az vm image list --output table
az vm image list --offer Ubuntu --all --output table
# Create VM from custom image
az vm create \
--resource-group myResourceGroup \
--name myVM \
--image /subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.Compute/images/{image-name} \
--admin-username azureuser \
--generate-ssh-keys
Managing Virtual Machines
# List VMs
az vm list --output table
az vm list --resource-group myResourceGroup --output table
# Show VM details
az vm show --resource-group myResourceGroup --name myVM
# Start/Stop/Restart VM
az vm start --resource-group myResourceGroup --name myVM
az vm stop --resource-group myResourceGroup --name myVM
az vm restart --resource-group myResourceGroup --name myVM
# Deallocate VM (stop billing for compute)
az vm deallocate --resource-group myResourceGroup --name myVM
# Resize VM
az vm resize --resource-group myResourceGroup --name myVM --size Standard_D4s_v3
# Delete VM
az vm delete --resource-group myResourceGroup --name myVM --yes
# Get public IP address
az vm show --resource-group myResourceGroup --name myVM \
--show-details --query publicIps --output tsv
Connecting to VMs
# SSH to Linux VM
ssh azureuser@<public-ip>
# SSH using Azure CLI (with Entra ID authentication; requires the ssh extension)
az ssh vm --resource-group myResourceGroup --name myVM
# RDP to Windows VM
# Use Remote Desktop client with public IP and credentials
# Run command on VM
az vm run-command invoke \
--resource-group myResourceGroup \
--name myVM \
--command-id RunShellScript \
--scripts "apt-get update && apt-get install -y nginx"
# For Windows
az vm run-command invoke \
--resource-group myResourceGroup \
--name myVM \
--command-id RunPowerShellScript \
--scripts "Install-WindowsFeature -Name Web-Server"
Virtual Machine Scale Sets
# Create a scale set
az vmss create \
--resource-group myResourceGroup \
--name myScaleSet \
--image Ubuntu2204 \
--upgrade-policy-mode automatic \
--admin-username azureuser \
--generate-ssh-keys \
--instance-count 2 \
--vm-sku Standard_B2s
# List scale sets
az vmss list --output table
# Show scale set instances
az vmss list-instances \
--resource-group myResourceGroup \
--name myScaleSet \
--output table
# Scale manually
az vmss scale \
--resource-group myResourceGroup \
--name myScaleSet \
--new-capacity 5
# Configure autoscale
az monitor autoscale create \
--resource-group myResourceGroup \
--resource myScaleSet \
--resource-type Microsoft.Compute/virtualMachineScaleSets \
--name autoscale-config \
--min-count 2 \
--max-count 10 \
--count 2
# Add autoscale rule (scale out on CPU > 70%)
az monitor autoscale rule create \
--resource-group myResourceGroup \
--autoscale-name autoscale-config \
--condition "Percentage CPU > 70 avg 5m" \
--scale out 1
# Update instances
az vmss update-instances \
--resource-group myResourceGroup \
--name myScaleSet \
--instance-ids "*"
# Delete scale set
az vmss delete --resource-group myResourceGroup --name myScaleSet
Storage Accounts
Azure Storage provides scalable, durable cloud storage for various data types.
graph TB
subgraph "Storage Account"
A[Storage Account] --> B[Blob Storage]
A --> C[File Storage]
A --> D[Queue Storage]
A --> E[Table Storage]
B --> B1[Containers]
B1 --> B2[Block Blobs]
B1 --> B3[Append Blobs]
B1 --> B4[Page Blobs]
C --> C1[File Shares]
C1 --> C2[Directories]
C2 --> C3[Files]
end
Key Concepts
- Blob Storage: Object storage for unstructured data (files, images, backups)
- File Storage: Managed file shares accessible via SMB/NFS
- Queue Storage: Message queuing for application communication
- Table Storage: NoSQL key-value store for structured data
- Access Tiers: Hot, Cool, Cold, and Archive for cost optimisation
Creating Storage Accounts
# Create storage account
az storage account create \
--name mystorageaccount \
--resource-group myResourceGroup \
--location uksouth \
--sku Standard_LRS \
--kind StorageV2
# Create with redundancy options
az storage account create \
--name mystorageaccount \
--resource-group myResourceGroup \
--location uksouth \
--sku Standard_GRS \
--kind StorageV2 \
--access-tier Hot
# List storage accounts
az storage account list --output table
# Get storage account keys
az storage account keys list \
--account-name mystorageaccount \
--resource-group myResourceGroup \
--output table
# Get connection string
az storage account show-connection-string \
--name mystorageaccount \
--resource-group myResourceGroup \
--output tsv
Blob Storage Operations
# Set environment variables for convenience
export AZURE_STORAGE_ACCOUNT=mystorageaccount
export AZURE_STORAGE_KEY=$(az storage account keys list \
--account-name mystorageaccount \
--resource-group myResourceGroup \
--query '[0].value' --output tsv)
# Create container
az storage container create --name mycontainer
# Create container with public access
az storage container create --name public-container --public-access blob
# List containers
az storage container list --output table
# Upload blob
az storage blob upload \
--container-name mycontainer \
--name myfile.txt \
--file /path/to/local/file.txt
# Upload directory
az storage blob upload-batch \
--destination mycontainer \
--source /path/to/local/directory
# List blobs
az storage blob list --container-name mycontainer --output table
# Download blob
az storage blob download \
--container-name mycontainer \
--name myfile.txt \
--file /path/to/download/file.txt
# Download directory
az storage blob download-batch \
--destination /path/to/local/directory \
--source mycontainer
# Delete blob
az storage blob delete --container-name mycontainer --name myfile.txt
# Generate SAS token for blob
az storage blob generate-sas \
--container-name mycontainer \
--name myfile.txt \
--permissions r \
--expiry 2026-12-31T23:59:59Z \
--output tsv
# Set blob tier
az storage blob set-tier \
--container-name mycontainer \
--name myfile.txt \
--tier Cool
File Storage Operations
# Create file share
az storage share create --name myfileshare --quota 100
# List file shares
az storage share list --output table
# Create directory
az storage directory create --share-name myfileshare --name mydir
# Upload file
az storage file upload \
--share-name myfileshare \
--source /path/to/local/file.txt \
--path mydir/file.txt
# List files
az storage file list --share-name myfileshare --path mydir --output table
# Download file
az storage file download \
--share-name myfileshare \
--path mydir/file.txt \
--dest /path/to/download/file.txt
# Mount file share on Linux
sudo mount -t cifs //<storage-account>.file.core.windows.net/<share-name> /mnt/myshare \
-o vers=3.0,username=<storage-account>,password=<storage-key>,dir_mode=0777,file_mode=0777
Queue Storage Operations
# Create queue
az storage queue create --name myqueue
# List queues
az storage queue list --output table
# Add message to queue
az storage message put --queue-name myqueue --content "Hello, World!"
# Peek at messages (without removing)
az storage message peek --queue-name myqueue
# Get messages (removes from queue)
az storage message get --queue-name myqueue
# Clear all messages
az storage message clear --queue-name myqueue
# Delete queue
az storage queue delete --name myqueue
Table Storage Operations
# Create table
az storage table create --name mytable
# List tables
az storage table list --output table
# Insert entity
az storage entity insert --table-name mytable \
--entity PartitionKey=pk1 RowKey=rk1 Name=John Age=30
# Query entities
az storage entity query --table-name mytable
# Query with filter
az storage entity query --table-name mytable \
--filter "PartitionKey eq 'pk1'"
# Delete entity
az storage entity delete --table-name mytable \
--partition-key pk1 --row-key rk1
# Delete table
az storage table delete --name mytable
Microsoft Entra ID and RBAC
Microsoft Entra ID (formerly Azure Active Directory / Azure AD) provides identity and access management services. The CLI commands retain the az ad prefix.
flowchart TB
subgraph "Identity Management"
A[Entra ID Tenant]
A --> B[Users]
A --> C[Groups]
A --> D[Service Principals]
A --> E[Managed Identities]
end
subgraph "Access Control"
F[Role Definitions]
G[Role Assignments]
H[Scopes]
end
B --> G
C --> G
D --> G
E --> G
F --> G
H --> G
H --> H1[Management Group]
H --> H2[Subscription]
H --> H3[Resource Group]
H --> H4[Resource]
Key Concepts
- Tenant: Dedicated instance of Microsoft Entra ID for an organisation
- Service Principal: Identity for applications to access Azure resources
- Managed Identity: Automatic identity management for Azure services
- RBAC: Role-Based Access Control for fine-grained permissions
- Built-in Roles: Owner, Contributor, Reader, and service-specific roles
User and Group Management
# List users
az ad user list --output table
# Create user
az ad user create \
--display-name "John Smith" \
--user-principal-name john@contoso.onmicrosoft.com \
--password "SecureP@ssw0rd!"
# Show user details
az ad user show --id john@contoso.onmicrosoft.com
# Delete user
az ad user delete --id john@contoso.onmicrosoft.com
# List groups
az ad group list --output table
# Create group
az ad group create --display-name "DevOps Team" --mail-nickname devops-team
# Add user to group
az ad group member add \
--group "DevOps Team" \
--member-id <user-object-id>
# List group members
az ad group member list --group "DevOps Team" --output table
# Check group membership
az ad group member check \
--group "DevOps Team" \
--member-id <user-object-id>
Service Principals
# Create service principal
az ad sp create-for-rbac --name myServicePrincipal
# Create with specific role and scope
az ad sp create-for-rbac \
--name myServicePrincipal \
--role Contributor \
--scopes /subscriptions/<subscription-id>/resourceGroups/myResourceGroup
# List service principals
az ad sp list --all --output table
# Show service principal details
az ad sp show --id <app-id>
# Reset service principal credentials
az ad sp credential reset --id <app-id>
# Delete service principal
az ad sp delete --id <app-id>
# Create managed identity
az identity create \
--resource-group myResourceGroup \
--name myManagedIdentity
# Assign managed identity to VM
az vm identity assign \
--resource-group myResourceGroup \
--name myVM \
--identities myManagedIdentity
Role Assignments
# List role definitions
az role definition list --output table
# List built-in roles
az role definition list --query "[?roleType=='BuiltInRole'].{Name:roleName, Description:description}" --output table
# Show role definition details
az role definition list --name "Contributor"
# Assign role to user
az role assignment create \
--assignee john@contoso.onmicrosoft.com \
--role "Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/myResourceGroup
# Assign role to service principal
az role assignment create \
--assignee <app-id> \
--role "Reader" \
--scope /subscriptions/<subscription-id>
# Assign role to group
az role assignment create \
--assignee-object-id <group-object-id> \
--assignee-principal-type Group \
--role "Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/myResourceGroup
# List role assignments
az role assignment list --output table
# List role assignments for specific user
az role assignment list --assignee john@contoso.onmicrosoft.com --output table
# List role assignments for resource group
az role assignment list \
--scope /subscriptions/<subscription-id>/resourceGroups/myResourceGroup \
--output table
# Delete role assignment
az role assignment delete \
--assignee john@contoso.onmicrosoft.com \
--role "Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/myResourceGroup
Custom Role Definitions
# Create custom role from JSON
cat << 'EOF' > custom-role.json
{
"Name": "Custom VM Operator",
"Description": "Can start and stop VMs",
"Actions": [
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/powerOff/action",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachines/read"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/<subscription-id>"
]
}
EOF
az role definition create --role-definition custom-role.json
# Update custom role
az role definition update --role-definition custom-role.json
# Delete custom role
az role definition delete --name "Custom VM Operator"
Azure Kubernetes Service (AKS)
AKS is a managed Kubernetes service for deploying and managing containerised applications.
flowchart TB
subgraph "AKS Cluster"
A[Control Plane<br/>Managed by Azure]
subgraph "Node Pools"
B[System Node Pool]
C[User Node Pool 1]
D[User Node Pool 2]
end
A --> B
A --> C
A --> D
B --> B1[Node]
B --> B2[Node]
C --> C1[Node]
C --> C2[Node]
C --> C3[Node]
end
E[Azure Container Registry] --> A
F[Azure Monitor] --> A
G[Entra ID] --> A
Key Concepts
- Control Plane: Managed by Azure, includes API server, scheduler, etcd
- Node Pools: Groups of nodes with the same configuration
- System Node Pool: Runs critical system pods (CoreDNS, kube-proxy)
- User Node Pools: Run application workloads
Creating AKS Clusters
# Create basic AKS cluster
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 3 \
--enable-addons monitoring \
--generate-ssh-keys
# Create cluster with specific settings
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 3 \
--node-vm-size Standard_D2s_v3 \
--kubernetes-version 1.33.0 \
--network-plugin azure \
--enable-managed-identity \
--enable-addons monitoring \
--generate-ssh-keys
# Create cluster with Azure CNI
# (--docker-bridge-address was removed when AKS moved to containerd)
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 3 \
--network-plugin azure \
--vnet-subnet-id /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet> \
--dns-service-ip 10.2.0.10 \
--service-cidr 10.2.0.0/24
# List available Kubernetes versions
az aks get-versions --location uksouth --output table
Managing AKS Clusters
# List AKS clusters
az aks list --output table
# Show cluster details
az aks show --resource-group myResourceGroup --name myAKSCluster
# Get cluster credentials
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
# Get credentials with admin access
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --admin
# Upgrade cluster (check available versions with `az aks get-versions`)
az aks upgrade \
--resource-group myResourceGroup \
--name myAKSCluster \
--kubernetes-version 1.34.0
# Scale cluster
az aks scale \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 5
# Start cluster (if stopped)
az aks start --resource-group myResourceGroup --name myAKSCluster
# Stop cluster
az aks stop --resource-group myResourceGroup --name myAKSCluster
# Delete cluster
az aks delete --resource-group myResourceGroup --name myAKSCluster --yes
Node Pool Management
# List node pools
az aks nodepool list \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--output table
# Add node pool
az aks nodepool add \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name gpunodepool \
--node-count 2 \
--node-vm-size Standard_NC4as_T4_v3 \
--labels workload=gpu
# Add spot node pool (cost savings)
az aks nodepool add \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name spotnodepool \
--node-count 3 \
--priority Spot \
--eviction-policy Delete \
--spot-max-price -1
# Scale node pool
az aks nodepool scale \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name gpunodepool \
--node-count 5
# Upgrade node pool
az aks nodepool upgrade \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name gpunodepool \
--kubernetes-version 1.34.0
# Delete node pool
az aks nodepool delete \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name gpunodepool
# Enable cluster autoscaler
az aks nodepool update \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name nodepool1 \
--enable-cluster-autoscaler \
--min-count 1 \
--max-count 10
AKS with Azure Container Registry
# Create ACR
az acr create \
--resource-group myResourceGroup \
--name myacr \
--sku Basic
# Attach ACR to AKS
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--attach-acr myacr
# Or during cluster creation
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--attach-acr myacr \
--node-count 3 \
--generate-ssh-keys
App Service
Azure App Service is a fully managed platform for building, deploying, and scaling web applications.
flowchart LR
A[Source Code] --> B[Build]
B --> C[App Service Plan]
C --> D[Web App]
D --> E[Custom Domain]
D --> F[SSL Certificate]
D --> G[Deployment Slots]
G --> G1[Production]
G --> G2[Staging]
G --> G3[Dev]
Key Concepts
- App Service Plan: Defines compute resources and pricing tier
- Web App: The application hosted on the plan
- Deployment Slots: Live apps with their own hostnames for staging
- Scaling: Vertical (scale up) or horizontal (scale out)
Creating App Service
# Create App Service Plan
az appservice plan create \
--name myAppServicePlan \
--resource-group myResourceGroup \
--sku B1 \
--is-linux
# Create Web App
az webapp create \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--name mywebapp \
--runtime "PYTHON:3.11"
# List available runtimes
az webapp list-runtimes --os-type linux
# Create Web App for containers
az webapp create \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--name mycontainerapp \
--deployment-container-image-name nginx:latest
# List web apps
az webapp list --output table
# Show web app details
az webapp show --resource-group myResourceGroup --name mywebapp
Deploying Applications
# Deploy from local Git
az webapp deployment source config-local-git \
--resource-group myResourceGroup \
--name mywebapp
# Get deployment URL
az webapp deployment list-publishing-credentials \
--resource-group myResourceGroup \
--name mywebapp \
--query scmUri --output tsv
# Deploy from GitHub
az webapp deployment source config \
--resource-group myResourceGroup \
--name mywebapp \
--repo-url https://github.com/user/repo \
--branch main \
--manual-integration
# Deploy from ZIP
az webapp deployment source config-zip \
--resource-group myResourceGroup \
--name mywebapp \
--src app.zip
# Deploy using Azure CLI
az webapp up \
--resource-group myResourceGroup \
--name mywebapp \
--runtime "PYTHON:3.11"
# Restart web app
az webapp restart --resource-group myResourceGroup --name mywebapp
# View logs
az webapp log tail --resource-group myResourceGroup --name mywebapp
Configuration
# Set application settings (environment variables)
az webapp config appsettings set \
--resource-group myResourceGroup \
--name mywebapp \
--settings KEY1=VALUE1 KEY2=VALUE2
# List application settings
az webapp config appsettings list \
--resource-group myResourceGroup \
--name mywebapp \
--output table
# Set connection string
az webapp config connection-string set \
--resource-group myResourceGroup \
--name mywebapp \
--settings MyDbConnection='Server=...' \
--connection-string-type SQLAzure
# Configure startup command
az webapp config set \
--resource-group myResourceGroup \
--name mywebapp \
--startup-file "gunicorn --bind=0.0.0.0 app:app"
# Enable application logging
az webapp log config \
--resource-group myResourceGroup \
--name mywebapp \
--application-logging filesystem \
--level verbose
# Configure custom domain
az webapp config hostname add \
--resource-group myResourceGroup \
--webapp-name mywebapp \
--hostname www.example.com
Scaling
# Scale up (change pricing tier; Premium v4 (P1V4) is the latest
# generation where regionally available)
az appservice plan update \
--resource-group myResourceGroup \
--name myAppServicePlan \
--sku P1V3
# Scale out (increase instances)
az appservice plan update \
--resource-group myResourceGroup \
--name myAppServicePlan \
--number-of-workers 3
# Configure autoscale
az monitor autoscale create \
--resource-group myResourceGroup \
--resource myAppServicePlan \
--resource-type Microsoft.Web/serverfarms \
--name autoscale-config \
--min-count 1 \
--max-count 10 \
--count 1
# Add autoscale rule
az monitor autoscale rule create \
--resource-group myResourceGroup \
--autoscale-name autoscale-config \
--condition "CpuPercentage > 70 avg 5m" \
--scale out 1
Deployment Slots
# Create deployment slot
az webapp deployment slot create \
--resource-group myResourceGroup \
--name mywebapp \
--slot staging
# List slots
az webapp deployment slot list \
--resource-group myResourceGroup \
--name mywebapp \
--output table
# Deploy to slot
az webapp deployment source config-zip \
--resource-group myResourceGroup \
--name mywebapp \
--slot staging \
--src app.zip
# Swap slots
az webapp deployment slot swap \
--resource-group myResourceGroup \
--name mywebapp \
--slot staging \
--target-slot production
# Configure slot settings (sticky)
az webapp config appsettings set \
--resource-group myResourceGroup \
--name mywebapp \
--slot staging \
--slot-settings IS_STAGING=true
Azure Functions
Azure Functions is a serverless compute service for running event-triggered code.
flowchart LR
subgraph "Triggers"
A[HTTP]
B[Timer]
C[Queue]
D[Blob]
E[Event Hub]
end
F[Azure Function]
subgraph "Bindings"
G[Input]
H[Output]
end
A --> F
B --> F
C --> F
D --> F
E --> F
G --> F
F --> H
H --> I[Queue]
H --> J[Blob]
H --> K[Cosmos DB]
H --> L[HTTP Response]
Key Concepts
- Triggers: Events that cause a function to run
- Bindings: Declarative connections to other services
- Function App: Container for one or more functions
- Hosting Plans: Consumption (pay per execution), Premium, or Dedicated
Creating Functions
# Create Function App (Python 3.12 is the last version supported on
# Linux Consumption; use 3.13 on Flex Consumption/Premium/App Service plans)
az functionapp create \
--resource-group myResourceGroup \
--consumption-plan-location uksouth \
--runtime python \
--runtime-version 3.12 \
--functions-version 4 \
--name myfunctionapp \
--storage-account mystorageaccount
# Create with Premium plan
az functionapp plan create \
--resource-group myResourceGroup \
--name myPremiumPlan \
--location uksouth \
--sku EP1
az functionapp create \
--resource-group myResourceGroup \
--plan myPremiumPlan \
--runtime python \
--runtime-version 3.13 \
--functions-version 4 \
--name myfunctionapp \
--storage-account mystorageaccount
# List function apps
az functionapp list --output table
# Show function app details
az functionapp show --resource-group myResourceGroup --name myfunctionapp
Local Development
# Install Azure Functions Core Tools
npm install -g azure-functions-core-tools@4 --unsafe-perm true
# Create new function project
func init MyFunctionProject --python
# Create new function
cd MyFunctionProject
func new --name HttpTrigger --template "HTTP trigger"
# Run locally
func start
# Test locally
curl http://localhost:7071/api/HttpTrigger?name=Azure
Deploying Functions
# Deploy from local project
func azure functionapp publish myfunctionapp
# Deploy from ZIP
az functionapp deployment source config-zip \
--resource-group myResourceGroup \
--name myfunctionapp \
--src functionapp.zip
# Deploy from GitHub
az functionapp deployment source config \
--resource-group myResourceGroup \
--name myfunctionapp \
--repo-url https://github.com/user/repo \
--branch main
# View deployment status
az functionapp deployment source show \
--resource-group myResourceGroup \
--name myfunctionapp
Configuration and Bindings
# Set application settings
az functionapp config appsettings set \
--resource-group myResourceGroup \
--name myfunctionapp \
--settings "MyStorageConnection=..." "ApiKey=..."
# List settings
az functionapp config appsettings list \
--resource-group myResourceGroup \
--name myfunctionapp \
--output table
# Get function URL
az functionapp function show \
--resource-group myResourceGroup \
--name myfunctionapp \
--function-name HttpTrigger \
--query invokeUrlTemplate --output tsv
Example Function with Bindings
# function_app.py
import azure.functions as func
import logging
app = func.FunctionApp()
# HTTP trigger with queue output binding
@app.route(route="orders", methods=["POST"])
@app.queue_output(arg_name="msg", queue_name="orders", connection="AzureStorageConnection")
def create_order(req: func.HttpRequest, msg: func.Out[str]) -> func.HttpResponse:
order = req.get_json()
msg.set(str(order))
return func.HttpResponse("Order created", status_code=201)
# Queue trigger with blob output binding
@app.queue_trigger(arg_name="msg", queue_name="orders", connection="AzureStorageConnection")
@app.blob_output(arg_name="outputblob", path="processed/{rand-guid}.json", connection="AzureStorageConnection")
def process_order(msg: func.QueueMessage, outputblob: func.Out[str]):
logging.info(f"Processing order: {msg.get_body().decode()}")
outputblob.set(msg.get_body().decode())
# Timer trigger
@app.timer_trigger(schedule="0 */5 * * * *", arg_name="timer")
def scheduled_task(timer: func.TimerRequest):
logging.info("Timer function executed")
# Blob trigger
@app.blob_trigger(arg_name="blob", path="uploads/{name}", connection="AzureStorageConnection")
def process_upload(blob: func.InputStream):
logging.info(f"Processing blob: {blob.name}, Size: {blob.length} bytes")
Monitoring Functions
# View logs
az functionapp log tail --resource-group myResourceGroup --name myfunctionapp
# View execution history
az monitor metrics list \
--resource /subscriptions/<sub-id>/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myfunctionapp \
--metric "FunctionExecutionCount" \
--interval PT1H
# Enable Application Insights
az functionapp config appsettings set \
--resource-group myResourceGroup \
--name myfunctionapp \
--settings "APPINSIGHTS_INSTRUMENTATIONKEY=<instrumentation-key>"
Container Instances and Container Apps
Azure provides multiple container hosting options for different use cases.
flowchart TB
subgraph "Container Options"
A[Azure Container Instances<br/>Simple, fast deployment]
B[Azure Container Apps<br/>Microservices, scaling]
C[Azure Kubernetes Service<br/>Full orchestration]
end
D[Simple Tasks] --> A
E[Microservices] --> B
F[Complex Workloads] --> C
A --> G[Single Container Groups]
B --> H[Managed Kubernetes]
C --> I[Full Kubernetes Control]
Azure Container Instances (ACI)
# Create container instance
az container create \
--resource-group myResourceGroup \
--name mycontainer \
--image nginx:latest \
--dns-name-label mycontainer \
--ports 80
# Create with environment variables
az container create \
--resource-group myResourceGroup \
--name myapp \
--image myacr.azurecr.io/myapp:latest \
--registry-login-server myacr.azurecr.io \
--registry-username myacr \
--registry-password <password> \
--dns-name-label myapp \
--ports 8080 \
--environment-variables DB_HOST=mydb.database.azure.com API_KEY=secret123 \
--cpu 2 \
--memory 4
# Create multi-container group from YAML
cat << 'EOF' > container-group.yaml
apiVersion: 2021-10-01
location: uksouth
name: mycontainergroup
properties:
containers:
- name: frontend
properties:
image: nginx
ports:
- port: 80
resources:
requests:
cpu: 1.0
memoryInGB: 1.5
- name: backend
properties:
image: myacr.azurecr.io/backend:latest
ports:
- port: 8080
resources:
requests:
cpu: 1.0
memoryInGB: 1.5
osType: Linux
ipAddress:
type: Public
ports:
- protocol: tcp
port: 80
EOF
az container create \
--resource-group myResourceGroup \
--file container-group.yaml
# List container instances
az container list --output table
# Show container details
az container show --resource-group myResourceGroup --name mycontainer
# View logs
az container logs --resource-group myResourceGroup --name mycontainer
# Attach to container (interactive)
az container attach --resource-group myResourceGroup --name mycontainer
# Execute command in container
az container exec \
--resource-group myResourceGroup \
--name mycontainer \
--exec-command "/bin/bash"
# Restart container
az container restart --resource-group myResourceGroup --name mycontainer
# Delete container
az container delete --resource-group myResourceGroup --name mycontainer --yes
Azure Container Apps
# Create Container Apps environment
az containerapp env create \
--name myEnvironment \
--resource-group myResourceGroup \
--location uksouth
# Create Container App
az containerapp create \
--name mycontainerapp \
--resource-group myResourceGroup \
--environment myEnvironment \
--image nginx:latest \
--target-port 80 \
--ingress external \
--min-replicas 1 \
--max-replicas 10
# Create from ACR with secrets
az containerapp create \
--name myapp \
--resource-group myResourceGroup \
--environment myEnvironment \
--image myacr.azurecr.io/myapp:latest \
--registry-server myacr.azurecr.io \
--registry-username myacr \
--registry-password <password> \
--target-port 8080 \
--ingress external \
--env-vars "DB_HOST=mydb.database.azure.com" "API_KEY=secretref:api-key" \
--secrets "api-key=mysecretvalue"
# List Container Apps
az containerapp list --output table
# Show Container App details
az containerapp show \
--resource-group myResourceGroup \
--name mycontainerapp
# Update Container App
az containerapp update \
--resource-group myResourceGroup \
--name mycontainerapp \
--image nginx:1.25
# Configure scaling rules
az containerapp update \
--resource-group myResourceGroup \
--name mycontainerapp \
--min-replicas 2 \
--max-replicas 20 \
--scale-rule-name http-rule \
--scale-rule-type http \
--scale-rule-http-concurrency 100
# View logs
az containerapp logs show \
--resource-group myResourceGroup \
--name mycontainerapp
# Create revision
az containerapp revision copy \
--resource-group myResourceGroup \
--name mycontainerapp \
--image myacr.azurecr.io/myapp:v2
# List revisions
az containerapp revision list \
--resource-group myResourceGroup \
--name mycontainerapp \
--output table
# Traffic splitting between revisions
az containerapp ingress traffic set \
--resource-group myResourceGroup \
--name mycontainerapp \
--revision-weight mycontainerapp--rev1=80 mycontainerapp--rev2=20
# Delete Container App
az containerapp delete --resource-group myResourceGroup --name mycontainerapp --yes
Virtual Networks and NSGs
Azure Virtual Networks provide isolated network environments for Azure resources.
flowchart TB
subgraph "Virtual Network 10.0.0.0/16"
subgraph "Subnet A - 10.0.1.0/24"
A[VM1]
B[VM2]
end
subgraph "Subnet B - 10.0.2.0/24"
C[Web Server]
D[App Server]
end
subgraph "Subnet C - 10.0.3.0/24"
E[Database]
end
end
F[Internet] --> G[NSG]
G --> C
H[VPN Gateway] --> A
C --> I[NSG]
I --> D
D --> J[NSG]
J --> E
Key Concepts
- Virtual Network (VNet): Logically isolated network in Azure
- Subnet: Segment of a VNet with its own address range
- Network Security Group (NSG): Firewall rules for network traffic
- Service Endpoints: Secure connectivity to Azure services
- Private Endpoints: Private IP for Azure PaaS services
Creating Virtual Networks
# Create virtual network
az network vnet create \
--resource-group myResourceGroup \
--name myVNet \
--address-prefix 10.0.0.0/16 \
--subnet-name default \
--subnet-prefix 10.0.1.0/24
# List virtual networks
az network vnet list --output table
# Show VNet details
az network vnet show --resource-group myResourceGroup --name myVNet
# Add subnet
az network vnet subnet create \
--resource-group myResourceGroup \
--vnet-name myVNet \
--name backend \
--address-prefix 10.0.2.0/24
# List subnets
az network vnet subnet list \
--resource-group myResourceGroup \
--vnet-name myVNet \
--output table
# Update subnet
az network vnet subnet update \
--resource-group myResourceGroup \
--vnet-name myVNet \
--name backend \
--network-security-group myNSG
# Delete subnet
az network vnet subnet delete \
--resource-group myResourceGroup \
--vnet-name myVNet \
--name backend
Network Security Groups
# Create NSG
az network nsg create \
--resource-group myResourceGroup \
--name myNSG
# List NSGs
az network nsg list --output table
# Show NSG rules
az network nsg rule list \
--resource-group myResourceGroup \
--nsg-name myNSG \
--output table
# Add inbound rule (allow SSH)
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name AllowSSH \
--priority 100 \
--direction Inbound \
--access Allow \
--protocol Tcp \
--source-address-prefixes '*' \
--source-port-ranges '*' \
--destination-address-prefixes '*' \
--destination-port-ranges 22
# Add inbound rule (allow HTTP/HTTPS)
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name AllowWeb \
--priority 110 \
--direction Inbound \
--access Allow \
--protocol Tcp \
--source-address-prefixes Internet \
--source-port-ranges '*' \
--destination-address-prefixes '*' \
--destination-port-ranges 80 443
# Add inbound rule (deny all)
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name DenyAll \
--priority 4096 \
--direction Inbound \
--access Deny \
--protocol '*' \
--source-address-prefixes '*' \
--source-port-ranges '*' \
--destination-address-prefixes '*' \
--destination-port-ranges '*'
# Add outbound rule
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name AllowStorageOutbound \
--priority 100 \
--direction Outbound \
--access Allow \
--protocol Tcp \
--source-address-prefixes VirtualNetwork \
--source-port-ranges '*' \
--destination-address-prefixes Storage \
--destination-port-ranges 443
# Associate NSG with subnet
az network vnet subnet update \
--resource-group myResourceGroup \
--vnet-name myVNet \
--name default \
--network-security-group myNSG
# Associate NSG with NIC
az network nic update \
--resource-group myResourceGroup \
--name myVMNic \
--network-security-group myNSG
# Delete NSG rule
az network nsg rule delete \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name AllowSSH
Public IP and Load Balancer
# Create public IP
az network public-ip create \
--resource-group myResourceGroup \
--name myPublicIP \
--sku Standard \
--allocation-method Static
# Create load balancer
az network lb create \
--resource-group myResourceGroup \
--name myLoadBalancer \
--sku Standard \
--public-ip-address myPublicIP \
--frontend-ip-name myFrontEnd \
--backend-pool-name myBackEndPool
# Create health probe
az network lb probe create \
--resource-group myResourceGroup \
--lb-name myLoadBalancer \
--name myHealthProbe \
--protocol tcp \
--port 80
# Create load balancer rule
az network lb rule create \
--resource-group myResourceGroup \
--lb-name myLoadBalancer \
--name myHTTPRule \
--protocol tcp \
--frontend-port 80 \
--backend-port 80 \
--frontend-ip-name myFrontEnd \
--backend-pool-name myBackEndPool \
--probe-name myHealthProbe
VNet Peering
# Create VNet peering
az network vnet peering create \
--resource-group myResourceGroup \
--name VNet1ToVNet2 \
--vnet-name myVNet1 \
--remote-vnet /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/myVNet2 \
--allow-vnet-access
# List peerings
az network vnet peering list \
--resource-group myResourceGroup \
--vnet-name myVNet1 \
--output table
# Delete peering
az network vnet peering delete \
--resource-group myResourceGroup \
--name VNet1ToVNet2 \
--vnet-name myVNet1
Quick Reference
| Task | Command |
|---|---|
| Login | az login |
| Set subscription | az account set --subscription "name" |
| Create resource group | az group create --name rg --location uksouth |
| Create VM | az vm create --resource-group rg --name vm --image Ubuntu2204 |
| Start/Stop VM | az vm start/stop --resource-group rg --name vm |
| Create storage account | az storage account create --name sa --resource-group rg |
| Upload blob | az storage blob upload --container-name c --name n --file f |
| Create AKS cluster | az aks create --resource-group rg --name aks --node-count 3 |
| Get AKS credentials | az aks get-credentials --resource-group rg --name aks |
| Create web app | az webapp create --resource-group rg --plan plan --name app |
| Deploy web app | az webapp deployment source config-zip --resource-group rg --name app --src app.zip |
| Create function app | az functionapp create --resource-group rg --name func --storage-account sa |
| Create container instance | az container create --resource-group rg --name ci --image img |
| Create VNet | az network vnet create --resource-group rg --name vnet --address-prefix 10.0.0.0/16 |
| Create NSG | az network nsg create --resource-group rg --name nsg |
| Add NSG rule | az network nsg rule create --resource-group rg --nsg-name nsg --name rule |
| Assign role | az role assignment create --assignee user --role "Role" --scope scope |
| List resources | az resource list --resource-group rg --output table |
Common Issues and Solutions
| Issue | Solution |
|---|---|
AuthorizationFailed error |
Check role assignments with az role assignment list --assignee <user>. Ensure correct scope and permissions. |
ResourceNotFound error |
Verify resource group and resource names. Check subscription context with az account show. |
| VM not starting | Check quota limits: az vm list-usage --location uksouth. Request increase if needed. |
| Cannot SSH to VM | Verify NSG rules allow port 22. Check public IP is assigned. Use az vm run-command as alternative. |
| Storage access denied | Check firewall rules and network access. Verify SAS token or storage key is valid and not expired. |
| AKS cluster unreachable | Run az aks get-credentials to refresh kubeconfig. Check cluster status with az aks show. |
| Web app deployment fails | Check deployment logs: az webapp log tail. Verify runtime matches application. Check startup command. |
| Function not triggering | Verify connection strings for bindings. Check Application Insights for errors. Review function.json configuration. |
| Container instance failing | Check container logs: az container logs. Verify image pull permissions. Check resource limits. |
| VNet peering not working | Ensure peering is created on both VNets. Check for overlapping address spaces. Verify allow-vnet-access is enabled. |
| NSG rules not applying | Check rule priority (lower number = higher priority). Verify NSG is associated with subnet or NIC. |
| Service principal expired | Reset credentials: az ad sp credential reset --id <app-id>. Update application configuration. |
| Subscription quota exceeded | Request increase via Azure Portal or az quota request create. Consider different region. |
| Slow Azure CLI commands | Update CLI: az upgrade. Use --no-wait for async operations. Use JMESPath queries to reduce output. |
Related Topics
The following topics complement this Azure cheatsheet and would be valuable additions:
- Terraform - Infrastructure as Code for Azure resources, enabling repeatable deployments and version-controlled infrastructure
- Azure DevOps / GitHub Actions - CI/CD pipelines for automated deployment to Azure services
- Prometheus & Grafana - Monitoring and observability for Azure workloads, especially AKS clusters
- Helm - Package management for Kubernetes applications on AKS
- Ansible - Configuration management and automation for Azure VMs and resources
- Container Security - Image scanning, runtime security, and best practices for Azure container services