Onboarding : Azure Virtual Machine

Key concepts

  • Virtual Machine (VM)
  • CLI
  • VM
  • Availability Set
  • Scale Set
  • Snapshot (from disk)
  • Image (from vm)

Manage VM

VM management roles (RBAC)
  • Virtual Machine Contributor
  • Network Contributor
  • Storage Account Contributor

Note: The roles have to be assigned to an Azure AD Group instead of a user

To have a proper management on VMs, different management opptions have to be used

Available VM commands
az vm [subcommands]
createCreate a new virtual machine
deallocateDeallocate a virtual machine
deleteDelete a virtual machine
listList the created virtual machines in your subscription
open-portOpen a specific network port for inbound traffic
restartRestart a virtual machine
showGet the details for a virtual machine
startStart a stopped virtual machine
stopStop a running virtual machine
updateUpdate a property of a virtual machine
# Create a Linux virtual machine
az vm create \
  --resource-group [sandbox resource group name] \
  --location westus \
  --name SampleVM \
  --image UbuntuLTS \
  --admin-username azureuser \
  --generate-ssh-keys \
  --verbose # Azure CLI tool waits while the VM is being created.
    # Or
  --no-wait # option to tell the Azure CLI tool to return immediately and have Azure continue creating the VM in the background.
# output
  "fqdns": "",
  "id": "/subscriptions/<subscription-id>/resourceGroups/Learn-2568d0d0-efe3-4d04-a08f-df7f009f822a/providers/Microsoft.Compute/virtualMachines/SampleVM",
  "location": "westus",
  "macAddress": "00-0D-3A-58-F8-45",
  "powerState": "VM running",
  "privateIpAddress": "",
  "publicIpAddress": "",
  "resourceGroup": "2568d0d0-efe3-4d04-a08f-df7f009f822a",
  "zones": ""

  # generate-ssh-keys flag: This parameter is used for Linux distributions and creates 
  # a pair of security keys so we can use the ssh tool to access the virtual machine remotely. 
  # The two files are placed into the .ssh folder on your machine and in the VM. If you already 
  # have an SSH key named id_rsa in the target folder, then it will be used rather than having a new key generated.

# Connecting to the VM with SSH
ssh azureuser@<public-ip-address>

# for exit

# Listing images
az vm image list --output table

# Getting all images
az vm image list --sku WordPress --output table --all # t is helpful to filter the list with the --publisher, --sku or –-offer options.

# Location-specific images
az vm image list --location eastus --output table

Pre-defined VM sizes

Azure defines a set of pre-defined VM sizes for Linux and Windows to choose from based on the expected usage.

General purposeDsv3, Dv3, DSv2, Dv2, DS, D, Av2, A0-7Balanced CPU-to-memory. Ideal for dev/test and small to medium applications and data solutions.
Compute optimizedFs, FHigh CPU-to-memory. Good for medium-traffic applications, network appliances, and batch processes.
Memory optimizedEsv3, Ev3, M, GS, G, DSv2, DS, Dv2, DHigh memory-to-core. Great for relational databases, medium to large caches, and in-memory analytics.
Storage optimizedLsHigh disk throughput and IO. Ideal for big data, SQL, and NoSQL databases.
GPU optimizedNV, NCSpecialized VMs targeted for heavy graphic rendering and video editing.
High performanceH, A8-11Our most powerful CPU VMs with optional high-throughput network interfaces (RDMA).
# get a list of the available sizes
az vm list-sizes --location eastus --output table

# output
MaxDataDiskCount    MemoryInMb  Name                      NumberOfCores    OsDiskSizeInMb    ResourceDiskSizeInMb
------------------  ------------  ----------------------  ---------------  ----------------  ----------------------
                 2          2048  Standard_B1ms                         1           1047552                    4096
                 2          1024  Standard_B1s                          1           1047552                    2048
                 4          8192  Standard_B2ms                         2           1047552                   16384
                 4          4096  Standard_B2s                          2           1047552                    8192
                 8         16384  Standard_B4ms                         4           1047552                   32768
                16         32768  Standard_B8ms                         8           1047552                   65536
                 4          3584  Standard_DS1_v2 (default)             1           1047552                    7168
                 8          7168  Standard_DS2_v2                       2           1047552                   14336
                16         14336  Standard_DS3_v2                       4           1047552                   28672
                32         28672  Standard_DS4_v2                       8           1047552                   57344
                64         57344  Standard_DS5_v2                      16           1047552                  114688
                64       3891200  Standard_M128-32ms                  128           1047552                 4096000
                64       3891200  Standard_M128-64ms                  128           1047552                 4096000
                64       3891200  Standard_M128ms                     128           1047552                 4096000
                64       2048000  Standard_M128s                      128           1047552                 4096000
                64       1024000  Standard_M64                         64           1047552                 8192000
                64       1792000  Standard_M64m                        64           1047552                 8192000
                64       2048000  Standard_M128                       128           1047552                16384000
                64       3891200  Standard_M128m                      128           1047552                16384000

# Specify a size during VM creation
az vm create \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM2 \
    --image UbuntuLTS \
    --admin-username azureuser \
    --generate-ssh-keys \
    --verbose \
    --size "Standard_DS5_v2"

# Get available VM Size
# Before a resize is requested, we must check to see if the desired size is available in the cluster our VM is part of.
az vm list-vm-resize-options \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM \
    --output table

# Resize an existing VM 
az vm resize \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM \
    --size Standard_D2s_v3

This will return a list of all the possible size configurations available in the resource group. If the size we want isn’t available in our cluster, but is available in the region, we can deallocate the VM. This command will stop the running VM and remove it from the current cluster without losing any resources. Then we can resize it, which will re-create the VM in a new cluster where the size configuration is available.

# List VMs
az vm list

# Output types
az vm list --output table|json|jsonc|tsv

# Getting the IP address
az vm list-ip-addresses -n SampleVM -o table
# output
VirtualMachine    PublicIPAddresses    PrivateIPAddresses
----------------  -------------------  --------------------

# Getting VM details
az vm show --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 --name SampleVM
# we could change to a table format, but that omits almost all of the interesting data. Instead, we can turn to a built-in query language for JSON called JMESPath.
# https://jmespath.org/

# Adding filters to queries with JMESPath
  "people": [
      "name": "Fred",
      "age": 28
      "name": "Barney",
      "age": 25
      "name": "Wilma",
      "age": 27

# poeple is an array
# output
    "name": "Barney",
    "age": 25

people[?age > '25'] 
# output
    "name": "Fred",
    "age": 28
    "name": "Wilma",
    "age": 27

people[?age > '25'].[name]
# output

# Filtering our Azure CLI queries
az vm show \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM \
    --query "osProfile.adminUsername"

az vm show \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM \
    --query hardwareProfile.vmSize

az vm show \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM \
    --query "networkProfile.networkInterfaces[].id"

az vm show \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM \
    --query "networkProfile.networkInterfaces[].id" -o tsv

# Stopping a VM
az vm stop \
    --name SampleVM \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844

# We can verify it has stopped by attempting to ping the public IP address, using ssh, or through the vm get-instance-view command.
az vm get-instance-view \
    --name SampleVM \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --query "instanceView.statuses[?starts_with(code, 'PowerState/')].displayStatus" -o tsv

# Starting a VM    
az vm start \
    --name SampleVM \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844

# Restarting a VM
az vm start \
    --name SampleVM \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844

# Install NGINX web server
# 1.
z vm list-ip-addresses --name SampleVM --output table

# 2.
ssh azureuser@<PublicIPAddress>

# 3.
sudo apt-get -y update && sudo apt-get -y install nginx

# 4.

# Retrieve our default page
# Either
curl -m 10 <PublicIPAddress>
# Or
# in browser try the public ip address

# This command will fail because the Linux virtual machine doesn't expose
# port 80 (http) through the network security group that secures the network 
# connectivity to the virtual machine. We can change this with the Azure CLI command vm open-port.

# open oprt
az vm open-port \
    --port 80 \
    --resource-group learn-5d4bcefe-17c2-4db6-aba8-3f25d2c54844 \
    --name SampleVM

# output of curl command
<!DOCTYPE html>
<title>Welcome to nginx!</title>
body {
    width: 35em;
    margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif;
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>

Source: https://docs.microsoft.com/en-us/learn/modules/manage-virtual-machines-with-azure-cli/

Availability Set

Scale Set



  • Managed disk supports creating a managed Custome image
  • We can create image from custom VHD in a storage account or directly from generalized VM (via sysprepped VM command)
    • This process capture a single image
    • this image contains all managed disks associated with a VM, including both OS, and Data.

Image vs. Snapshot

With managed disks, you can take an image of a generalized VM that has been deallocated.It’s copy of disk in a specific point of time.
This image includes all managed disks attached to this VM. it applies only to one disk.
This image can be used to create a Vm.Sanpshot doesn’t have awareness of any disk except the one it contains.

If a VM has only one OS disk, we can take a snapshot of the disk or take image of VM and create a VM from either snapshot or the image.

You owe your dreams your courage.

Koleka Putuma

Published by parisamoosavinezhad

- Software Engineer - Software Architect - Software and database specialist - Cloud solution architect

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: