Getting started with Azure and VMs

Leon Brown
10 min readFeb 26, 2022

I want to describe how I recently rebooted my Azure account. No free account for me as I signed up then let it lapse.

I show how to start using Azure VMs to deploy a meaningful piece of infrastructure. I refer to prices as I go along and have updated the conclusion once the bills were in. The cost analysis at the end shows I spent 2p during this exercise. Whilst Azure provide prices up front, this usually requires a search engine to locate, some things are over sold, other priced. Coming full circle and checking the costs afterwards is a great feedback loop for learning.

Hopefully I will make this process clear enough that you can hit the ground running and not waste your free (or other) credit like I did.

Signing up

Azure give $200 credit with which you’re expected to avail yourself of their pricier services. By burning through it in 30 days. I was too busy with work and training to actually use Azure at the time.

When my 30 days were up I was pestered with prompts to upgrade, or else lose something about my account. Linux Academy provided sandboxed Azure environments for my training so I let my own account expire.

Now, after about 12 months I “upgraded” (it feels like starting fresh for so many reasons) to PAYGO. I had an inkling of the value of each service from time served in network operations and using AWS. Azure has Resource Groups, specifically for lifecycle management and avoiding unexpected bills.

final screen in the sign up

Azure do have a 12 month introductory offer, in addition to the $200, 30 day one. The 512 MB (B1S) VM that would have been free, is a mere £6.42 (in UK South region) a month.

First VM

Hey big spender! When I launched the new VM wizard I was immediately suggested a £63.11 (in UK) per month, D2s_v3 size. From the wizard’s interface I could immediately tell that the B series would be the cheapest. B1ms, for a master node has 2GB and is £12.84 (UK) a month. B1s has 1GB and will do for the other nodes. About £25.50 (UK) a month plus associated costs, like disks.

I’ll test the water with a quick and cheap B1ls at £3.21/month. Let’s try the portal and capture the ARM template it offers before considering Infrastructure as Code (IaC) options.

Basics

create vm, basics

Giving the VM a name auto-populates the resource group field to create a new one. Choose an OS, and VM size. I select my public key to save Azure the trouble. Azure wants an RSA key but I give them an ed25519 one (redacted in above screenshot) and ignore their muted protestations:

Having to access the “Market Place” for the OS image felt unnatural. Whilst there don’t appear to be costs associated with most of the Ubuntu images Azure has an interactive VM pricing page. The “Ubuntu Advantage Standard” B1ls is over four times the price of the free (for 12 months) Ubuntu B1ls (0.45p/hour)!

With the only Ubuntu in the initial drop-drown being the 4-year old version 18.04 I proceeded to the marketplace. Here is the drop-down after finding (the free) 20.04 for myself:

suggested images

There are a lot of superfluous filters in the marketplace. Here are the results of filtering for Ubuntu OS:

images filtered by OS: Ubuntu

This feels like a marketplace to earn money. It would appear they are hiding fixed prices, which means subduing advertisement of their being free. Let’s try filtering for “Ubuntu” and “Free”:

marketplace for images, filtered by ubunu os and free price

That’s disappointing, the frontrunners from the previous search, Ubuntu as the OS, are missing. Half are actually not free (including bring your own license (BYOL)) and only one is, obviously, Ubuntu.

Just typing in the text search field proved far more intuitive and was how I found Ubuntu 20.04.

Disks

A standard SSD at 25p per 4GiB (E1) per month is preferable to a standard HDD at £1.27 for 32GiB (S4). IOPS and throughput are pretty similar at 500 and 60MB/s respectively. The SSD is more consistent and offers free bursting beyond these limits, particularly in throughput. Current prices are here.

With hindsight, we don’t get to choose the size of our OS disk, despite 2GB being plenty for Ubuntu server. The Ubuntu 20.04 (and Linux in general) disks are always 30GB, despite there not being a price for that size in Microsoft’s pricing page.

The cost of 100k disk operations, of up to 256KiB each, is 1.5p for SSD and 0.37p for HDD.

Networking

Defaults do nicely. Normally I’d tweak a security group, but this is my first time in Azure. I didn’t bother to tick “Delete public IP and NIC when VM is deleted”. Deleting the resource group will clean this up.

Management

Options here relate to high level concepts that I was already aware of but took the time to review their help pop-ups. I accepted the defaults.

Advanced

“Extensions” can be useful. Here we can add a customisation script, in the, “Custom Script For Linux” extension:

Unfortunately, there is no meaningful text area to edit the script in the portal, it requires a file, hindering rapid, iterative, development.

I can SSH in and paste my own script, without worrying about converting escape sequences. Neither Custom data and cloud init, nor User data sections serve as suitable alternatives.

I can leave all of this section to its defaults.

Tags

Not essential.

Review + create

“Validation failed. Required information is missing or not valid.” in red

That EC SSH key I gave when it wanted an RSA one raises the red flag here. About time it stopped me. Eventually I noticed a tiny red dot above the Basic tab. As expected, ed25519 is not acceptable for SSH key.

SSH Key. I’ll use RSA locally and save Azure the bother:

$ ssh-keygen -b 4096 -f ~/.ssh/azvm_rsa -C "this is a comment"
$ cat ~/.ssh/azvm_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDGIkn6R4DzIreHQhLRoggZAgjE9thz9r9KNc8OxG/gs3qsL9TX57bRoqorhjDsTQ7C/WyykGswHZGUuF9eVCIkSsUvkXaOyebgoFGQRp1NE+jLO6QjjCmYznVPZPkL4cL1rxLfVxNyy8y/qfDKjOWA3OUdOdM/zsvckb3SsRbj/wQiZcUbj/sQ+NrtYKC9Tx3GpCIF1L5nDzkpZH43ZDSj+anVEWSTF3Pwg5UuxAz49nCOB6QU9Lxr9z2Lmmql2wdbOcbq9rbDWiyuvTvucaEMEWJyqaJ611qobe63yTKfZqUdscppZgRtegq8a1l2hhNVTQ1Ilhmn/qYyIQldGBkcCpQmkmckGAOAvjDuYD9rZNSh2jAdFV29BU1dtECgoquqQKNQOXgp/hJDpsHbJlAqdfLNdA6Asen+VI6dMQNmV9GIj4O3E5nQHWHM4lxGNpX1kacU2rTYt3YFsBU5ZJXPx5TcK0QNoJ0en4OsdyvFwXkOeZzh7nmrInAgHt6cSyUrFcTv6K99ZpWi2jc9cRLVtVEDcnCUha6p94a+gKGkSbVW0u48ctPXyxtBh1NQPnPEoqpiYU90k/pDKVqlNzL9dx2FIHS/yvyubZ1pQvDS+aP8Wc5nDzF5UqOMJJ6xVqCHd/3iv/6prkE8CJ2wQujWowQ3DbB2K+GWw5X8UPG00Q== this is a comment

Review + create. The red dot is on this tab now. It wants my phone number, again! The price, 0.44p per hour, though it is not explicit, only covers the VM:

I downloaded the ARM “template for automation”. It consists of 210 lines in template.json and about 90 in parameters.json. Viewed in Azure:

The public key is conspicuous by its absence. template.json references the following field in parameters.json:

"adminPublicKey": {
"value": null
}

In fact, it is stored as a SecureString (confusingly) as can be seen in the deployment.json downloadable after the deployment completes:

"adminPublicKey": {
"type": "SecureString"
}

I hit create and 30s later it completed and displayed what was added for me:

  • network interface
  • public IP address
  • virtual network
  • NSG

I can find all of these in my resource group (not listed) which also contains my disk (again, not listed above). I head over to Cost Management but have to wait a day or so for costs to appear.

I click the disk and see it is 30GiB! I find and copy my IP address (ILPIP), unlike AWS, but reflecting their scarcity, this is a further 0.3p/hr.

Later, for comparison, I tried provisioning again, changing only the disk, from SSD to HDD, the hourly cost of 0.44p, displayed in this tab did not change. Hence the displayed cost is just that of the VM. MS’s VM pricing guide quoted 0.45p the day after.

Utilising this node

ssh azureuser@13.87.78.42 -i ~/.ssh/azvm_rsa

I know my master node needs 1700MB but let’s give this puny B1ls VM a test. It takes about 30s installing kubelet, kubeadm and kubectl, without error.

Performance test

I timed this step, prefixing it with time, using the same VM but changing HDD for SSD. I wait until 5 minutes of uptime have elapsed to promote consistent results.

For HDD:

real	0m54.301s
user 0m15.339s
sys 0m4.033s

For SSD:

real	0m39.659s
user 0m15.308s
sys 0m4.317s

time apt-get install -y kubelet kubeadm kubectl containerd required:

Need to get 111 MB of archives.
After this operation, 487 MB of additional disk space will be used.

I feel this a relevant evaluation of the two disk types, assuming of course that it won’t just be sitting idle! I repeated 3 more times for the HDDs, they take about 52s on average, so about 25% slower.

kubeadm init

kubeadm init

Here I get errors. I must configure the kernel for networking, just as I would with Vagrant VMs. Then I’m still left with 2 errors:

  • need 2 CPU cores
  • need 1700MB RAM

If I ignore both of these it eventually fails with:

...
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[kubelet-check] Initial timeout of 40s passed.
Unfortunately, an error has occurred:
timed out waiting for the condition
This error is likely caused by:
- The kubelet is not running
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'
...

CPU can be time sliced, memory is a physical requirement.

Clean up

That’s as far as I go with this VM. I head over to Resource Groups and “Delete resource group”. Everything in the resource group gets deleted. Still no mention of my public key.

Reflections

This was a look at quickly getting in and using an Azure VM. Azure makes it very easy. I wouldn’t bother with IaC for this few VMs, and demonstration purposes.

Going from the B1ms to a dual core, B2s, VM doubles costs. I can push on with a single core by ignoring “preflight” errors:

kubeadm init --ignore-preflight-errors=NumCPU

I’ve a second part in the works where I’ll show the planned VMs described above in action, with fewer screen shots as I repeat the processes illustrated above. I’ve already written about the virtualised Kubernetes Cluster and its implementation in Vagrant, and updated it with how Azure works differently from Vagrant.

Cost Analysis

The month rolled over and my reading indicated bills would appear mere hours after using Azure services. I headed back to Cost Management in the portal, and then to Cost Analysis. Since I had no running services there would be no spending forecast and I selected the previous month. After a few seconds the data materialised, defaulting to the “AccumulatedCosts” view:

Accumulated Costs

That pie chart is amazingly useful for quantities smaller than the smallest unit (1p). Everything else just reported <1p, which isn’t so helpful for extrapolating relative costs. But the pie chart! I can break down those services later but it’s basically what I discovered when creating the VMs (and this bill covered creating all 3, much larger VMs for Kubernetes).

Virtual networks are free. The part of that service I am billed for is the IP. A sixth of the VM cost. It’s actually almost equal to the cost of the cheapest VM, but for more useful nodes it’s less an issue. That covers 7 of the 9p. Probably more, you’ll see bandwidth is invisible in the pie chart as it’s only charged on data leaving the cloud. Storage was cheap, I made it 28% and 38% of the B1ls cost, respectively for HDD and SSD. Those projections appear vindicated.

The next view, “CostByResource”, and Group by “Resource type” doesn’t even mention outbound traffic:

Finally, the first thing I looked up when the data showed up, Invoice Details. Grouping by meter (I don’t know either) was the default. Here we see how little the b1ms cost, the IP address almost matching the cost!

--

--