# Azure CLI Cheat Sheet — Compute: VM & AKS

> **Tool:** Azure CLI (az)
> **Category:** Cloud CLIs
> **Verified against:** Azure CLI 2.87.0, flags verified via `az <cmd> --help`, 2026-08-21
> **Official docs:** https://learn.microsoft.com/cli/azure

Virtual machine lifecycle, and AKS (Azure Kubernetes Service) cluster/node-pool management.

## Creating a VM

```bash
az vm create \
  --resource-group my-rg --name my-vm \
  --image Ubuntu2204 --size Standard_DS2_v2 \
  --admin-username deploy --generate-ssh-keys
```

`--generate-ssh-keys` creates a new SSH key pair if one doesn't already exist at the default path and reuses it if it does — convenient for one-off VMs, but for anything scripted/repeatable, pass an explicit `--ssh-key-values` pointing at a managed key instead.

## Listing and inspecting VMs

```bash
az vm list --resource-group my-rg --output table
az vm list --show-details --output table               # + public IP, FQDN, power state (slower call)
az vm show --resource-group my-rg --name my-vm
```

## Starting, stopping, and deleting VMs

```bash
az vm start --resource-group my-rg --name my-vm
az vm stop --resource-group my-rg --name my-vm            # power off, still billed for allocated compute
az vm deallocate --resource-group my-rg --name my-vm       # power off AND release the compute allocation
az vm delete --resource-group my-rg --name my-vm --yes
```

`stop` and `deallocate` are not the same: `stop` powers the OS off but Azure still holds the underlying hardware allocation (still billed); `deallocate` releases it entirely (billing stops, but a dynamic public IP can change on next start). This is the Azure-specific gotcha equivalent to AWS's stop-vs-terminate distinction — get it backwards and you either keep paying or lose an IP unexpectedly.

## Creating an AKS cluster

```bash
az aks create \
  --resource-group my-rg --name my-cluster \
  --node-count 3 --generate-ssh-keys
```

## Getting kubectl credentials

```bash
az aks get-credentials --resource-group my-rg --name my-cluster
```

Same role as `aws eks update-kubeconfig` / `gcloud container clusters get-credentials` — merges a context into your local kubeconfig so `kubectl` can talk to the cluster.

## Listing clusters and node pools

```bash
az aks list --resource-group my-rg --output table
az aks nodepool list --resource-group my-rg --cluster-name my-cluster --output table
```

## Scaling a node pool

```bash
az aks scale --resource-group my-rg --name my-cluster --node-count 5
az aks scale --resource-group my-rg --name my-cluster --nodepool-name userpool --node-count 5
```

## Adding, updating, and removing node pools

```bash
az aks nodepool add \
  --resource-group my-rg --cluster-name my-cluster \
  --name userpool --node-count 3 --node-vm-size Standard_DS2_v2
az aks nodepool show --resource-group my-rg --cluster-name my-cluster --name userpool
az aks nodepool delete --resource-group my-rg --cluster-name my-cluster --name userpool
```

A cluster always keeps at least one *system* node pool (`--mode System`, the default for the pool created by `az aks create`) for core cluster components — application workloads typically go on a separate *user* node pool (`--mode User`) so you can scale, upgrade, or delete it independently without touching system components.

## Enabling and configuring the cluster autoscaler on a node pool

```bash
az aks nodepool update \
  --resource-group my-rg --cluster-name my-cluster --name userpool \
  --enable-cluster-autoscaler --min-count 2 --max-count 8
az aks nodepool update \
  --resource-group my-rg --cluster-name my-cluster --name userpool \
  --disable-cluster-autoscaler
```

`--min-count`/`--max-count` only take effect with `--enable-cluster-autoscaler` — the fixed `--node-count` from `az aks scale` is ignored once autoscaling is on, since the autoscaler owns the node count from that point.
