One of the most powerful features in Azure IaaS that it allows us to create Windows and Linux servers in minutes. It also offers a wide array of pre-built images to choose from with only the OS installed (virgin machine) or customized with other installed features and applications. (e.g. Windows Server 2012 R2, Ubuntu Server 14.04 LTS, SQL Server 2014, SharePoint Server Farm...)

vms in azure

In this post we will take a look at creating Virtual Machines (VMs) in Azure using a mix of the Azure Portal and PowerShell commands

Table of Contents

  • Architecture
  • Creating Virtual Machines in Azure
    • Creating a MySQL VM using the Azure portal
    • Create Windows Server 2012 VM using PowerShell
  • Summary


The two VMs created in this post will be deployed to the Azure Virtual Network (VNet) that was created in part 1 here

The VM that is created in the front-end subnet will be publicly accessible over HTTP/HTTPs where our internet facing applications are deployed. The back-end subnet however, where our database server will live, is not accessible over the internet and even outgoing connections to the internet are denied, the only access is through the RDP port from incoming connections over the internet and port 3306 from the front-end subnet to connect to the database servers. This makes it a much safer environment for our database.


Creating a MySQL VM using the Azure portal

We will use the Azure Portal to create a MySQL Stack image from the Azure gallery by Bitnami. This a preconfigured image of a MySQL server linux machine created and published by Bitnami. Notice that 3rd parties can publish their own approved images to the Azure gallery. There could be charges by the publisher in addition to the VM provided by Microsoft.

Bitnami doesn't charge anything for using this image, but Microsoft will charge you based on the VM size which we'll select later on. Here is the description of this image by Bitnami:

Bitnami MySQL Stack is a pre-configured, ready to run image for running MySQL on Microsoft Azure. MySQL is a fast, reliable, scalable, and easy to use open-source relational database system. MySQL Server is intended for mission-critical, heavy-load production systems as well as for embedding into mass-deployed software.

For more information on the Bitnami MySQL Stack visit our website (https://bitnami.com/stack/mysql), wiki (https://wiki.bitnami.com) and forums (https://community.bitnami.com).

  1. Log-on to https://Portal.Azure.com

  2. Click on the "+ New" button on the top-left corner and type "MySQL" in the search field then press enter


  1. From the presented options select "MySQL" by Bitnami, then click the "Create" button. Make sure the "Resource Manager" option is selected from the drop down. Notice the description


  1. Next you will be presented with configuration options that is needed before actually deploying the machine. Enter the values for the basic configuration settings as described below then click "OK":
    • Name: Example-MySQL-VM
    • user name and password or SSH public key for authentication
    • In the resource group, If you are following from the previous post then you can select the same resource group that we used previously or you can create a new resource group for the resources that we'll be creating in this post.
    • Pick the location that is closest to you


  1. The second step is choosing the Size of the Linux virtual machine that the image will be deployed into. The prices displayed are for the VM only, other installed application licensing fees will be presented later on. However, there are no additional costs for this image other than what's presented here.

  2. Click on "View All" then scroll down until you find the "A0 Basic" instance this click select. This is the cheapest VM currently available and the charges will be minimum for this example.



  1. Now in the Settings step, if you selected the same resource group we created in Part 1 then you only need to make sure we are using the Backend subnet and in the Network Security Group select "None" as we already have one applied on the subnet level. Otherwise, accept the default setting then click "OK"

Make sure to take a note of the storage account name created as we will use that for the other machine we are creating in PowerShell. Azure by default uses the VM name in lowercase and append a random number. In this case our storage account name is "exampleinfraeastus2585"


  1. Validate the Summary and click "OK"

  2. The Purchase screen next should show charges only applied by Microsoft for the selected VM instance size. Click on Purchase to provision the VM.


  1. Wait until the deployment is complete which should be about 5 minutes then you should see the VM information by clicking on the "Virtual Machines" menu.


After completing this you should have a Linux VM provisioned with MySQL Server installed and configured.

Create Windows Server 2012 VM using PowerShell

This example will show you how to create a Windows Server 2012 VM using ARM PowerShell commands. We will be using the same resource group we created/used for the MySQL VM, same Virtual Network and storage account. The VM will be deployed to the Frontend subnet that we created in Part 1 of this post.

Check Azure documentation "Create and configure a Windows Virtual Machine with Resource Manager and Azure PowerShell" for detailed reference of each command in the PowerShell script below

The code can be found here


# Set values for existing resource group and storage account names

# Set the existing virtual network and subnet index
$vnet=Get-AzureRMVirtualNetwork -Name $vnetName -ResourceGroupName $rgName

# Create the NIC
$pip=New-AzureRmPublicIpAddress -Name $nicName -ResourceGroupName $rgName -DomainNameLabel $domName -Location $locName -AllocationMethod Dynamic
$nic=New-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[$subnetIndex].Id -PublicIpAddressId $pip.Id

# Specify the name and size
$vm=New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize

# Add a 50 GB additional data disk
$storageAcc=Get-AzureRmStorageAccount -ResourceGroupName $rgName -Name $saName
$vhdURI=$storageAcc.PrimaryEndpoints.Blob.ToString() + "vhds/" + $vmName + $diskName  + ".vhd"
Add-AzureRmVMDataDisk -VM $vm -Name $diskLabel -DiskSizeInGB $diskSize -VhdUri $vhdURI -CreateOption empty

# Specify the image and local administrator account, and then add the NIC
$cred=Get-Credential -Message "Type the name and password of the local administrator account."
$vm=Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzureRmVMSourceImage -VM $vm -PublisherName $pubName -Offer $offerName -Skus $skuName -Version "latest"
$vm=Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id

# Specify the OS disk name and create the VM
$storageAcc=Get-AzureRmStorageAccount -ResourceGroupName $rgName -Name $saName
$osDiskUri=$storageAcc.PrimaryEndpoints.Blob.ToString() + "vhds/" + $vmName + $diskName  + ".vhd"
$vm=Set-AzureRmVMOSDisk -VM $vm -Name $diskName -VhdUri $osDiskUri -CreateOption fromImage
New-AzureRmVM -ResourceGroupName $rgName -Location $locName -VM $vm

In part 3 of this post, I will be exporting ARM deployment template documents in JSON format that defines the resources we created within the two resource groups we have so far. This JSON template can be deployed to Azure anytime to provision and reproduce the entire setup of our network and VMs in an automated way.

We'll also see how this template deployment can be authored, added to source control and lastly deployed from Visual Studio along with our applications to integrate the Application Lifecycle Management (ALM) with the infrastructure of our applications and allowing us to build the architecture in code.