Azure CLI command reference and core service reference for Microsoft Azure.
| Level | What it bounds | Notes |
|---|---|---|
| Tenant | Identity. One Entra ID directory. | Formerly Azure AD. Users, groups, and app registrations live here, not in a subscription. |
| Management group | Policy and RBAC across subscriptions. | Worth setting up before you have more than a handful of subscriptions. Retrofitting is tedious. |
| Subscription | Billing, quotas, and hard service limits. | Quotas are per region per subscription. Hitting a vCPU quota is a support ticket, not a setting. |
| Resource group | Lifecycle. A container you delete as a unit. | Group by what dies together, not by resource type. Its region only stores metadata — resources inside can live elsewhere. |
| Resource | The actual thing. | Identified by a full resource ID path. az resource show --ids works on any of them. |
- Storage account names are globally unique, 3–24 characters, lowercase letters and digits only. No hyphens. This catches everyone once.
- Key Vault and several PaaS names are also globally unique — they become DNS names.
- Deleting a resource group deletes everything inside it, with one confirmation. Use resource locks on anything important.
- Not every service is in every region, and paired regions matter for geo-redundant storage failover.
- Availability zones exist only in some regions. Check before designing around them.
| Group | Command | Does |
|---|---|---|
| Auth | az login | Browser sign-in. --use-device-code for headless machines. |
| Auth | az account list -o table | Every subscription you can reach. |
| Auth | az account set -s "NAME_OR_ID" | Set the active subscription. Check this before anything destructive. |
| Auth | az account show -o table | Which subscription am I actually in right now. |
| Groups | az group create -n NAME -l eastus | Create a resource group. |
| Groups | az group delete -n NAME --no-wait | Deletes every resource inside. Add -y to skip the prompt — carefully. |
| Query | az resource list -g RG -o table | Everything in a resource group. |
| Query | az ... --query "[].{n:name,l:location}" -o table | JMESPath projection into readable columns. The most useful CLI skill to learn. |
| Query | az graph query -q "Resources | summarize count() by type" | Resource Graph — KQL across every subscription at once. Far faster than looping. |
| Query | az find "az vm" | Discover commands and common examples for a service. |
| VM | az vm create -g RG -n VM --image Ubuntu2204 --generate-ssh-keys | Create a VM plus its NIC, IP, and NSG. |
| VM | az vm list -d -o table | -d adds power state and public IP — usually what you wanted. |
| VM | az vm deallocate -g RG -n VM | Stops compute billing. az vm stop alone does not — see Gotchas. |
| VM | az vm run-command invoke -g RG -n VM --command-id RunShellScript --scripts "uptime" | Run a command without SSH or an open port. |
| Storage | az storage account create -n NAME -g RG --sku Standard_LRS | Name must be globally unique, lowercase alphanumeric. |
| Storage | az storage blob upload --auth-mode login ... | --auth-mode login uses your Entra identity instead of an account key. |
| Storage | azcopy sync SRC DST --recursive | Separate tool, dramatically faster for bulk transfer. |
| AKS | az aks get-credentials -g RG -n CLUSTER | Merge cluster creds into your kubeconfig. |
| AKS | az aks nodepool list -g RG --cluster-name C -o table | Node pools with sizes and counts. |
| Web | az webapp log tail -g RG -n APP | Live application logs. The fastest App Service debugging step. |
| Web | az webapp deployment slot swap -g RG -n APP --slot staging | Blue/green swap with warm-up. |
| RBAC | az role assignment list --assignee USER -o table | What a principal can actually do. |
| RBAC | az role assignment create --role "Reader" --assignee X --scope /subscriptions/... | Grant at a scope. Prefer groups over individual users. |
| Locks | az lock create --lock-type CanNotDelete -n prod --resource-group RG | Cheap protection against accidental deletion. Apply to production groups. |
| Deploy | az deployment group what-if -g RG -f main.bicep | Preview changes before deploying. The Bicep equivalent of a plan. |
| Category | Service | Use for | AWS analogue |
|---|---|---|---|
| Compute | Virtual Machines | Full control, lift-and-shift workloads. | EC2 |
| Compute | App Service | Managed web apps with slots and easy scaling. | Elastic Beanstalk |
| Compute | Functions | Event-driven serverless. | Lambda |
| Compute | Container Apps | Serverless containers with scale-to-zero. Usually the right first choice over AKS. | App Runner / Fargate |
| Compute | AKS | Managed Kubernetes. Control plane is free; you pay for nodes. | EKS |
| Storage | Blob Storage | Object storage. Hot / Cool / Cold / Archive tiers. | S3 |
| Storage | Azure Files | SMB/NFS shares you can mount. | EFS / FSx |
| Storage | Managed Disks | VM block storage. | EBS |
| Data | Azure SQL Database | Managed SQL Server. DTU or vCore pricing. | RDS for SQL Server |
| Data | Cosmos DB | Global NoSQL, multi-model. Watch RU/s billing. | DynamoDB |
| Data | PostgreSQL / MySQL Flexible Server | Managed open-source databases. | RDS |
| Network | Virtual Network | Private networking, subnets, peering. | VPC |
| Network | NSG | Stateful firewall rules on subnets or NICs. | Security Group + NACL |
| Network | Application Gateway | Layer 7 load balancing with WAF. | ALB + WAF |
| Network | Front Door | Global entry point, CDN, and WAF. | CloudFront + Global Accelerator |
| Ops | Monitor / Log Analytics | Metrics, logs, alerts. Query with KQL. | CloudWatch |
| Ops | Key Vault | Secrets, keys, certificates. | Secrets Manager + KMS |
| Ops | Azure Policy | Enforce or audit rules across scopes. | SCPs + Config |
- Log Analytics, Application Insights, Resource Graph, and Sentinel all use KQL. Learning it once pays off across all of them.
- Pipeline syntax:
TableName | where ... | summarize ... | order by ... - Always filter on time first —
| where TimeGenerated > ago(1h)— it's the difference between a fast query and an expensive one. | take 10while exploring, then build up the query.- Log Analytics bills on data ingested and retained. Verbose diagnostic settings on chatty resources get expensive quickly.
Turn one on
System-assigned is tied to the resource lifecycle and dies with it. User-assigned is a standalone resource several things can share.
Grant it access to something
Use it from code with zero credentials
The same pattern exists in the Python, JavaScript, Java, and Go SDKs.
- Assignments combine additively across scopes, and inherit downward from management group to resource.
- Deny assignments exist but you cannot create them directly — only Azure Blueprints and managed apps produce them. RBAC is otherwise allow-only, unlike AWS IAM's explicit deny.
- Built-in roles first — Reader, Contributor, Owner, plus hundreds of service-specific ones. Custom roles only when nothing fits.
- Contributor cannot grant access. That needs Owner or User Access Administrator, which is a useful separation.
- Assign to groups, not users. Auditing individual assignments across subscriptions is miserable.
- Use PIM for just-in-time elevation rather than standing Owner rights.
- Two permission models: legacy access policies and RBAC. Pick RBAC for new vaults — it's consistent with everything else.
- Soft delete is on and cannot be disabled. A deleted vault name stays reserved for the retention period, so recreating with the same name fails until you purge it.
- Enable purge protection on production vaults so a deletion can't be made permanent during the retention window.
- Reference secrets directly in App Service settings:
@Microsoft.KeyVault(SecretUri=...)— no code change needed. - Vault firewalls default to open. Restrict to selected networks and private endpoints for anything sensitive.
Gotchas
az vm stopdoes not stop billing. A stopped VM still reserves compute. You needaz vm deallocate. Stopping from inside the guest OS also keeps billing.- Deallocating releases a dynamic public IP — it will come back different. Use a static IP if the address matters.
- Managed disks bill whether or not the VM is running. Deleting a VM doesn't always delete its disks — check for orphans.
- Cosmos DB bills on provisioned RU/s continuously, not on usage. A forgotten test database is a real monthly cost.
- Log Analytics ingestion is a common runaway. Review diagnostic settings on chatty resources.
- Public IPs, unattached disks, and idle Application Gateways all bill while doing nothing. Azure Advisor flags most of them.
- Set a budget alert on every subscription on day one. It's free.
- Deleting a resource group deletes everything in it with one confirmation and no undo. Apply
CanNotDeletelocks to production groups. - Storage account names: globally unique, 3–24 chars, lowercase alphanumeric only. No hyphens, no uppercase.
- Quotas are per region per subscription, and raising them is a support request that takes time. Check before planning a large deployment.
- Soft delete applies to Key Vault, Blob storage, and others — a "deleted" name can stay reserved.
- NSG rules are evaluated by priority, lowest number first, and the first match wins. A broad allow at priority 100 silently overrides a specific deny at 200.
- Azure Policy in deny mode blocks deployments outright — an unexplained deployment failure is often a policy, and the error names it.
- Some settings are only in the portal, some only in the CLI, and the two occasionally use different names for the same thing.
- "Azure AD" is now Microsoft Entra ID. Documentation and CLI output still mix both names.
Tips
az graph query -q "Resources | where type =~ 'microsoft.compute/virtualmachines' | project name, location" queries every subscription at once — seconds instead of a shell loop.
A CanNotDelete lock takes one command and prevents the single worst Azure accident. Note it also blocks legitimate deletions until removed.
Bicep compiles to ARM but is far more readable, with real modules and type checking. az bicep decompile converts existing JSON templates.
what-if before deployingaz deployment group what-if previews exactly what a Bicep or ARM deployment changes — the equivalent of a Terraform plan.
shell.azure.com gives an authenticated shell with az, kubectl, Terraform, and Bicep preinstalled and persistent storage. No local setup.
--query plus -o table turns verbose JSON into exactly the columns you want. The biggest quality-of-life win in the CLI.