How to: Deploy a Virtual Machine to Azure using Bicep.

As some of the readers will know I became aware of and blogged about Bicep a month or so ago. Since then work has interfered with me giving this more than a cursory glance. However, I started to look at this in a little more detail last week.

Anyway, I was interested in seeing how I could use bicep to deploy a virtual machine to Azure. As a result of this I came up with the following simple example. Please note I only included the components that I would need to deploy and access a Windows VM, this included a VNet, Public IP (to allow for RDP connections) and a network interface. I have not included elements such as additional storage etc. and have made an assumption that a target resource group already exists.

Just for ease of use I have included everything in one bicep file and have not parametrising some of the variables, I will do this as part of my next post in this series which will take this starting file and extend it to allow deployment of multiple VMs.

First off, I needed to create a VNet and a subnet, to do this I used the following code.

resource VNet_Default 'Microsoft.Network/virtualNetworks@2020-08-01' = {
  name: 'VMVNet01'
  location: 'uksouth'
  properties: {
    addressSpace: {
      addressPrefixes: [
        '10.0.0.0/24'
      ]
    }
    subnets: [
      {
        name: 'VMSubnet'
        properties: {
          addressPrefix: '10.0.0.0/24'
          delegations: []
          privateEndpointNetworkPolicies: 'Enabled'
          privateLinkServiceNetworkPolicies: 'Enabled'
        }
      }
    ]
    virtualNetworkPeerings: []
    enableDdosProtection: false
  }
}

I also want a public IP address as this will allow me to access the VM via Remote Desktop. However, if you are using a bastion service or similar or want to use SSH then this may not be required or will need to be modified.

resource VM_PublicIP 'Microsoft.Network/publicIPAddresses@2021-02-01' ={
  name:'VMPublicIPAddress'
  location: 'uksouth'
  sku: {
    name: 'Basic'
    tier: 'Regional'
  }
  properties: {
    publicIPAddressVersion: 'IPv4'
    publicIPAllocationMethod: 'Dynamic'
  }
}

Finally, before getting to the VM creation template I need to add a network interface to the VM incorporating the VNet and Public IP address created using the above sections, to do this use the below structure.

resource NIC_VM 'Microsoft.Network/networkInterfaces@2020-08-01' = {
  name: 'nic01'
  location: 'uksouth'
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          publicIPAddress: {
            id: VM_PublicIP.id
          }
          privateIPAllocationMethod: 'Dynamic'
          subnet: {
            id: '${VNet_Default.id}/subnets/${'vmSubnet'}'
          }
          primary: true
          privateIPAddressVersion: 'IPv4'
        }
      }
    ]
  }
}

At this point I have the code for all the prerequisite components that the virtual machine requires. However, there is one area which required a bit of thought/work and that is the information needed for the underlying OS image, which includes the parameters publisher, offer, SKU & version. To get these details there are a suite of PowerShell commands which can be used for this (Get-AzVMImagePublisher, Get-AzVMImageOffer, Get-AzVMImageSku & Get-AzVMImage) see https://bit.ly/3lQanbd for more information and the links to the other commands.

Once you have the details for the above then use the following to create the VM.

resource VirtualMachine 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: 'VM01'
  location: 'uksouth'
  properties:{
    hardwareProfile: {
      vmSize:'Standard_D2s_v3'
      }
      storageProfile: {
        osDisk: {
          createOption: 'FromImage'
          osType: 'Windows'
          managedDisk: {
            storageAccountType: 'StandardSSD_LRS'
          }
        }
        imageReference: {
          publisher: 'MicrosoftWindowsDesktop'
          offer: 'Windows-10'
          sku: '19H1-ent'
          version: '18362.1198.2011031735'
        }
      }
      osProfile: {
        computerName: 'testcomputer'
        adminUsername: 'vmAdministrator'
        adminPassword: 'Adm1nP@55w0rd'
      }
      networkProfile: {
        networkInterfaces: [
          {
            id: NIC_VM.id
          }
        ]
      }
  }
}

At this point you will just need to run the following line of PowerShell to deploy the templates. Please note this is assuming that the resource group already exists.

New-AzResourceGroupDeployment -ResourceGroupName '<ResourceGroupName>' -TemplateFile ./<filename>.bicep 

I will upload the full sample code to GitHub and will publish the link here a little later.

UPDATED:
I have now uploaded the code samples to my public GitHub repository which can be found here https://bit.ly/3lQ2FOw.

Leave a comment

Website Built with WordPress.com.

Up ↑