1

Trying to automate spot instance creation using Azure CLI. Neither az vm list-sizes nor az vm list-skus --resource-type virtualMachines seems to show any "spot supported" filter(s).

I looked at terraform azurerm provider, but did not find any data source related to this under compute.

How does one figure out cheapest spot instance from a given region that meets some criteria (core count, memory, etc) ?

C:\Users\foo> az --version
azure-cli                         2.38.0

core                              2.38.0
telemetry                          1.0.6

Dependencies:
msal                            1.18.0b1
azure-mgmt-resource             21.1.0b1

Python location 'C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\python.exe'
Extensions directory 'C:\Users\foo\.azure\cliextensions'

Python (Windows) 3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 15:58:59) [MSC v.1929 32 bit (Intel)]

Legal docs and information: aka.ms/AzureCliLegal


Your CLI is up-to-date.

Please let us know how we are doing: https://aka.ms/azureclihats
and let us know if you're interested in trying out our newest features: https://aka.ms/CLIUXstudy

C:\Users\foo> terraform --version
Terraform v1.2.6
on windows_amd64

Parag Doke
  • 863
  • 7
  • 17

2 Answers2

1

Looking at the documentation:

The following VM sizes are not supported for Azure Spot Virtual Machines:

  • B-series
  • Promo versions of any size (like Dv2, NV, NC, H promo sizes)

So you could write an az cli query to exclude them:

az vm list-sizes --location "<location>" `
  --query "[?!contains(name, 'Promo') || !contains(name, 'Standard_B')]"

The Azure Pricing API could then help to find out pricing:

az rest --method get `
  --uri "https://prices.azure.com/api/retail/prices?`$filter=serviceName eq 'Virtual Machines' and armRegionName eq '<location>' and (contains(armSkuName, 'Promo') eq false and contains(armSkuName, 'Standard_B') eq false)"
Thomas
  • 24,234
  • 6
  • 81
  • 125
  • Thank you. This helps in omitting sizes that are unsupported for spot instances when using the CLI. What remains is how to figure the cheapest having say 2 cores. – Parag Doke Aug 01 '22 at 10:39
  • 1
    @ParagDoke added some infos regarding pricing, you could then figure out which VM you d like to use. – Thomas Aug 01 '22 at 10:50
  • 1
    Thank you @Thomas ! Your 2nd edit with the combination filter on rest sub-command should unblock anyone who is facing a similar situation. – Parag Doke Aug 01 '22 at 11:26
  • IMO, `(contains(skuName, 'Spot')) eq true` should avoid need to filter out unsupported sizes from rest sub-command. – Parag Doke Aug 01 '22 at 11:29
0

Based on the inputs from @Thomas, comfort with bash and jq, I installed mingw64 bash, downloaded jq executable and got this to work:

# build a list of sizes that match our criteria (say 4 cores) ... pick top 10
az vm list-sizes --location ${REGION} --query 'sort_by([?numberOfCores == `4` && !contains(name, `Promo`) && !contains(name, `Standard_B`)], &memoryInMb) | [:9].name' -o json > sizes.json

# now build a url to hit
# why not capture payload separately?
# https://stackoverflow.com/q/73206915/502914

echo -n 'https://prices.azure.com/api/retail/prices?$filter=serviceName eq "Virtual Machines" and armRegionName eq "' > url.txt
echo -n ${REGION} >> url.txt
echo -n '" and contains(skuName, "Spot") eq true' >> url.txt

# add size constraints to limit price response
jq -re '[.[] | "(armSkuName eq \"" + . + "\")"] | " and (" + join(" or ") + ")"' sizes.json >> url.txt

# for some reason, single quotes work better
sed -i -e "s/\"/'/g" url.txt

az rest --method get --url "$(cat url.txt)" --query "sort_by(Items, &unitPrice)" -o json > prices.json
Parag Doke
  • 863
  • 7
  • 17