Back to All Cheatsheet Libraries cheatsheets

Microsoft Azure

Azure CLI command reference and core service reference for Microsoft Azure.

Everything hangs off the hierarchy

Azure's structure is stricter than AWS's, and once you see it the rest of the platform makes sense. Policy and permissions flow downward through it, which is why getting the layout right early matters more than it seems.

Tenant (one Microsoft Entra ID directory — your identity boundary) └── Management Group (optional; policy + RBAC across many subscriptions) └── Subscription (billing + quota boundary) └── Resource Group (lifecycle boundary — delete it, delete everything in it) └── Resource (VM, storage account, database…)
Level What it bounds Notes
TenantIdentity. One Entra ID directory.Formerly Azure AD. Users, groups, and app registrations live here, not in a subscription.
Management groupPolicy and RBAC across subscriptions.Worth setting up before you have more than a handful of subscriptions. Retrofitting is tedious.
SubscriptionBilling, quotas, and hard service limits.Quotas are per region per subscription. Hitting a vCPU quota is a support ticket, not a setting.
Resource groupLifecycle. 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.
ResourceThe actual thing.Identified by a full resource ID path. az resource show --ids works on any of them.
Naming and regions
  • 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
Authaz loginBrowser sign-in. --use-device-code for headless machines.
Authaz account list -o tableEvery subscription you can reach.
Authaz account set -s "NAME_OR_ID"Set the active subscription. Check this before anything destructive.
Authaz account show -o tableWhich subscription am I actually in right now.
Groupsaz group create -n NAME -l eastusCreate a resource group.
Groupsaz group delete -n NAME --no-waitDeletes every resource inside. Add -y to skip the prompt — carefully.
Queryaz resource list -g RG -o tableEverything in a resource group.
Queryaz ... --query "[].{n:name,l:location}" -o tableJMESPath projection into readable columns. The most useful CLI skill to learn.
Queryaz graph query -q "Resources | summarize count() by type"Resource Graph — KQL across every subscription at once. Far faster than looping.
Queryaz find "az vm"Discover commands and common examples for a service.
VMaz vm create -g RG -n VM --image Ubuntu2204 --generate-ssh-keysCreate a VM plus its NIC, IP, and NSG.
VMaz vm list -d -o table-d adds power state and public IP — usually what you wanted.
VMaz vm deallocate -g RG -n VMStops compute billing. az vm stop alone does not — see Gotchas.
VMaz vm run-command invoke -g RG -n VM --command-id RunShellScript --scripts "uptime"Run a command without SSH or an open port.
Storageaz storage account create -n NAME -g RG --sku Standard_LRSName must be globally unique, lowercase alphanumeric.
Storageaz storage blob upload --auth-mode login ...--auth-mode login uses your Entra identity instead of an account key.
Storageazcopy sync SRC DST --recursiveSeparate tool, dramatically faster for bulk transfer.
AKSaz aks get-credentials -g RG -n CLUSTERMerge cluster creds into your kubeconfig.
AKSaz aks nodepool list -g RG --cluster-name C -o tableNode pools with sizes and counts.
Webaz webapp log tail -g RG -n APPLive application logs. The fastest App Service debugging step.
Webaz webapp deployment slot swap -g RG -n APP --slot stagingBlue/green swap with warm-up.
RBACaz role assignment list --assignee USER -o tableWhat a principal can actually do.
RBACaz role assignment create --role "Reader" --assignee X --scope /subscriptions/...Grant at a scope. Prefer groups over individual users.
Locksaz lock create --lock-type CanNotDelete -n prod --resource-group RGCheap protection against accidental deletion. Apply to production groups.
Deployaz deployment group what-if -g RG -f main.bicepPreview changes before deploying. The Bicep equivalent of a plan.
Category Service Use for AWS analogue
ComputeVirtual MachinesFull control, lift-and-shift workloads.EC2
ComputeApp ServiceManaged web apps with slots and easy scaling.Elastic Beanstalk
ComputeFunctionsEvent-driven serverless.Lambda
ComputeContainer AppsServerless containers with scale-to-zero. Usually the right first choice over AKS.App Runner / Fargate
ComputeAKSManaged Kubernetes. Control plane is free; you pay for nodes.EKS
StorageBlob StorageObject storage. Hot / Cool / Cold / Archive tiers.S3
StorageAzure FilesSMB/NFS shares you can mount.EFS / FSx
StorageManaged DisksVM block storage.EBS
DataAzure SQL DatabaseManaged SQL Server. DTU or vCore pricing.RDS for SQL Server
DataCosmos DBGlobal NoSQL, multi-model. Watch RU/s billing.DynamoDB
DataPostgreSQL / MySQL Flexible ServerManaged open-source databases.RDS
NetworkVirtual NetworkPrivate networking, subnets, peering.VPC
NetworkNSGStateful firewall rules on subnets or NICs.Security Group + NACL
NetworkApplication GatewayLayer 7 load balancing with WAF.ALB + WAF
NetworkFront DoorGlobal entry point, CDN, and WAF.CloudFront + Global Accelerator
OpsMonitor / Log AnalyticsMetrics, logs, alerts. Query with KQL.CloudWatch
OpsKey VaultSecrets, keys, certificates.Secrets Manager + KMS
OpsAzure PolicyEnforce or audit rules across scopes.SCPs + Config
KQL — the query language you actually need
  • 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 10 while exploring, then build up the query.
  • Log Analytics bills on data ingested and retained. Verbose diagnostic settings on chatty resources get expensive quickly.

Managed identities remove secrets entirely

The single highest-value Azure security feature. A managed identity gives a resource its own Entra identity, and Azure handles credential rotation — so there is no connection string, no client secret, and nothing to leak.

If you're storing an Azure credential in an app setting or a pipeline variable, a managed identity almost certainly removes the need for it.

1

Turn one on

az webapp identity assign -g RG -n APP # returns a principalId — that's the identity's object ID

System-assigned is tied to the resource lifecycle and dies with it. User-assigned is a standalone resource several things can share.

2

Grant it access to something

az role assignment create \ --assignee <principalId> \ --role "Key Vault Secrets User" \ --scope $(az keyvault show -n MYVAULT --query id -o tsv)
3

Use it from code with zero credentials

// DefaultAzureCredential picks up the managed identity in Azure // and your az login locally — same code both places. var client = new SecretClient( new Uri("https://myvault.vault.azure.net/"), new DefaultAzureCredential());

The same pattern exists in the Python, JavaScript, Java, and Go SDKs.

RBAC
  • 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.
Key Vault
  • 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

Billing surprises
  • az vm stop does not stop billing. A stopped VM still reserves compute. You need az 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.
Other things that catch people
  • Deleting a resource group deletes everything in it with one confirmation and no undo. Apply CanNotDelete locks 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

Resource Graph over loops

az graph query -q "Resources | where type =~ 'microsoft.compute/virtualmachines' | project name, location" queries every subscription at once — seconds instead of a shell loop.

Lock production resource groups

A CanNotDelete lock takes one command and prevents the single worst Azure accident. Note it also blocks legitimate deletions until removed.

Bicep over ARM templates

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 deploying

az deployment group what-if previews exactly what a Bicep or ARM deployment changes — the equivalent of a Terraform plan.

Cloud Shell

shell.azure.com gives an authenticated shell with az, kubectl, Terraform, and Bicep preinstalled and persistent storage. No local setup.

Learn JMESPath

--query plus -o table turns verbose JSON into exactly the columns you want. The biggest quality-of-life win in the CLI.

Resources