azure CLI

2022-02-18 ยท 4 min read

Initial Setup #

Setup an Azure account:

Install the CLI #

Debian/Ubuntu/WSL #

$ curl -sL | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null

$ AZ_REPO=$(lsb_release -cs) echo "deb [arch=amd64] $AZ_REPO main" | sudo tee /etc/apt/sources.list.d/azure-cli.list

$ sudo apt update
$ sudo apt-get install azure-cli

macOS #

$ brew update
$ brew install azure-cli

CLI Login #

$ az login

If this isn't inside a docker container, you can just run az login, which will open the browser for you. When doing this in WSL2, use az login --use-device-code and open separately.

View available regions #

# Pull out the "name" field in each object and sort them
$ az account list-locations \
	--query "[].name | sort(@)"

(Optional) Configure default region #

$ az configure --defaults location=westus

Create a resource group #

$ az group create \
	--location westus \
	--name az account list-locations --query "[].name | sort(@)"

  "id": "/subscriptions/XXXXX-XXXX-XXXX-XXXX-XXXXX/resourceGroups/mygroup",
  "location": "westus",
  "managedBy": null,
  "name": "mygroup",
  "properties": {
    "provisioningState": "Succeeded"
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"

(Optional) Configure default resource group #

$ az configure --defaults group=mygroup

Create our VM #

  • Note: Azure only supports uploading RSA keys via the CLI (i.e., not Ed25519 or ECDSA). The bit-length must also be at least 2048. Don't worry though, we'll toss our usual Ed25519 pubkeys into the VM in just a sec!
$ az vm create \
	--name myvm \
	--size Standard_DC1s_v3 \
	--image Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest \
	--authentication-type ssh \
	--ssh-key-values ~/.ssh/ \
	--public-ip-sku Basic \
	--public-ip-address-dns-name "my-unique-name" \
	--public-ip-address-allocation Dynamic \
	--storage-sku "Standard_LRS"

  "fqdns": "",
  "id": "/subscriptions/XXXXX-XXXX-XXXX-XXXX-XXXXX/resourceGroups/mygroup/providers/Microsoft.Compute/virtualMachines/myvm",
  "location": "westus",
  "macAddress": "XX-XX-XX-XX-XX-XX",
  "powerState": "VM running",
  "privateIpAddress": "",
  "publicIpAddress": "XX.XX.XX.XX",
  "resourceGroup": "mygroup",
  "zones": ""

Let's quickly confirm that the DNS name resolves correctly:

$ dig +short A

Then let's make sure we can at least SSH into the VM:

$ ssh -i ~/.ssh/id_rsa4096

We can also dump all of our github pubkeys into the VM, so we don't need the -i arg anymore : )

$ ssh -i ~/.ssh/id_rsa4096 \ \
	"curl \"\" >> ~/.ssh/authorized_keys"

(FIXUP) Create a public IPv4+IPv6 addr + DNS record #

  • Note: the dns-name label must be unique across all customers in a region!
  • The final DNS name will look like <dns-name>.<location>

See: Azure Docs - virtual network public IP

See: Azure - public IP address pricing

# Create the IPv4 address
$ az network public-ip create \
	--name "mygroup-ip" \
	--allocation-method Dynamic \
	--dns-name "my-unique-name" \
	--sku Basic \
	--version IPv4

# Create the IPv6 address
$ az network public-ip create \
	--name "mygroup-ip" \
	--allocation-method Dynamic \
	--dns-name "my-unique-name" \
	--sku Basic \
	--version IPv6

  "publicIp": {
    "ddosSettings": null,
    "deleteOption": null,
    "dnsSettings": {
      "domainNameLabel": "my-unique-name",
      "fqdn": "",
      "reverseFqdn": null
    "extendedLocation": null,
    "id": "/subscriptions/XXXXXX-XXXX-XXXX-XXXX-XXXXXX/resourceGroups/mygroup/providers/Microsoft.Network/publicIPAddresses/mygroup-ip",
    "idleTimeoutInMinutes": 4,
    "ipAddress": null,
    "ipConfiguration": null,
    "ipTags": [],
    "linkedPublicIpAddress": null,
    "location": "westus",
    "migrationPhase": null,
    "name": "mygroup-ip",
    "natGateway": null,
    "provisioningState": "Succeeded",
    "publicIpAddressVersion": "IPv6",
    "publicIpAllocationMethod": "Dynamic",
    "publicIpPrefix": null,
    "resourceGroup": "sgxdev",
    "resourceGuid": "XXXXXX-XXXX-XXXX-XXXX-XXXXXX",
    "servicePublicIpAddress": null,
    "sku": {
      "name": "Basic",
      "tier": "Regional"
    "tags": null,
    "type": "Microsoft.Network/publicIPAddresses",
    "zones": null