azure | AZ-104 | | 72 views

Deploying Virtual Machines

  • compute
  • infrastructure-as-a-service
  • virtual-machines

This post walks through creating a virtual machine in Azure four different ways - PowerShell, the Azure CLI, an ARM template and the Azure portal - so you can see the same task from each angle.

Create a VM via PowerShell

Run the following command to create a VM. The Get-Credential parameter prompts you to type in the username and password to use for the VM:

New-AzVm `
  -ResourceGroupName 'az104-rg8' `
  -Name 'myPSVM' `
  -Location 'East US' `
  -Image 'Win2019Datacenter' `
  -Zone '1' `
  -Size 'Standard_D2s_v3' `
  -Credential (Get-Credential)

Once the command completes, use Get-AzVM to list the virtual machines in your resource group:

Get-AzVM -ResourceGroupName 'az104-rg8' -Status

Use Stop-AzVM to deallocate the virtual machine — type yes to confirm:

Stop-AzVM -ResourceGroupName 'az104-rg8' -Name 'myPSVM'

Create a VM via Azure CLI

Launch a Cloud Shell session and select Bash. Run the following command to create a virtual machine; when prompted, provide a username and password for the VM. While you wait, the az vm create command reference covers all the parameters associated with creating a virtual machine.

az vm create --name myCLIVM --resource-group az104-rg8 --image Ubuntu2204 --admin-username localadmin --generate-ssh-keys

Once the command completes, use az vm show to verify your machine was created:

az vm show --name myCLIVM --resource-group az104-rg8 --show-details --output table

Use az vm deallocate to deallocate your virtual machine — type Yes to confirm:

az vm deallocate --resource-group az104-rg8 --name myCLIVM

Create a VM via ARM Templates

An ARM template gives you a fully declarative, repeatable way to define the same VM — see the Azure Resource Manager Overview post for the concepts behind templates, parameters, and deployment. A basic VM template needs a virtual network, a public IP, a network interface, and the VM resource itself:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vmName": { "type": "string", "defaultValue": "myARMVM" },
    "adminUsername": { "type": "string" },
    "adminPassword": { "type": "securestring" },
    "location": { "type": "string", "defaultValue": "[resourceGroup().location]" }
  },
  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2023-05-01",
      "name": "myVNet",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ] },
        "subnets": [
          { "name": "default", "properties": { "addressPrefix": "10.0.0.0/24" } }
        ]
      }
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2023-05-01",
      "name": "myPublicIP",
      "location": "[parameters('location')]",
      "properties": { "publicIPAllocationMethod": "Dynamic" }
    },
    {
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2023-05-01",
      "name": "myNIC",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', 'myVNet')]",
        "[resourceId('Microsoft.Network/publicIPAddresses', 'myPublicIP')]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVNet', 'default')]" },
              "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'myPublicIP')]" }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2023-09-01",
      "name": "[parameters('vmName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', 'myNIC')]"
      ],
      "properties": {
        "hardwareProfile": { "vmSize": "Standard_D2s_v3" },
        "osProfile": {
          "computerName": "[parameters('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2019-Datacenter",
            "version": "latest"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            { "id": "[resourceId('Microsoft.Network/networkInterfaces', 'myNIC')]" }
          ]
        }
      }
    }
  ],
  "outputs": {}
}

This is deliberately minimal — no data disks, no availability set or zone, no NSG, just enough to stand up a working VM. See the ARM Templates post linked above for how to parameterise this further, break it into linked templates, or convert it into a template spec.

Create a Virtual Machine in the Azure Portal

Navigate to Virtual Machine Creation. Start the VM creation process via the Azure portal: click Create a resource, search for Virtual machine, then click Create.

Configure Basic Settings. Select your Azure subscription and either create a new resource group or choose an existing one.

Name the Virtual Machine. Assign a unique name to the VM. The name identifies the VM within the Azure environment — it doesn't need to be globally unique.

Select a Region. Choose the Azure region closest to your users or where related resources reside. Geographic proximity minimises latency and improves application performance, and cost can vary between regions too.

Configure Availability Options. Choose between no redundancy, an availability set, or an availability zone. This determines the level of fault tolerance for the VM — consider the application's requirements, and for a standalone VM, no redundancy is often sufficient.

Select a Security Type. Choose the appropriate security option. Trusted launch provides enhanced security features against boot-kits and root-kits, Standard is the baseline option, and there's also a Confidential VM option for workloads handling especially sensitive data. Worth noting: Azure has been progressively rolling out Trusted launch as the default for new Gen2 VMs.

Choose an Image. Select the operating system image for the VM — you can choose from a wide variety of Microsoft-provided images or images published by third-party vendors.

Configure VM Size. Select a VM size based on the workload requirements; the size determines the CPU, RAM, and other resources allocated to the VM. Consider the B-series for testing.

Configure Hibernation. Enable or disable hibernation. Hibernation allows you to pause and resume the VM, saving on compute costs when it's not in use.

Configure User Credentials. Set up a username and password for the VM — these credentials are used to log into the VM.

Configure Networking. Specify the virtual network, subnet, and public IP address settings, and choose whether to allow inbound public ports. Opening inbound ports allows external access to the VM, which can be a security risk, so carefully consider whether it's necessary.

Configure Licensing. If you have eligible Windows Server licences, enable Azure Hybrid Benefit to reduce licensing costs — this lets you apply your existing licences in Azure, saving money on licensing fees.

Sources