Share via


Disk partition in Azure VMs - using ARM Templates to specify disk configurations

It is considered a best practice to define your Azure Resources using ARM Templates. We all know that. But what about in-VM configurations that you needed like say disk partitions, and other similar things.

Well it turns out you can specify such post VM instantiation configuration changes, which are actually not executed by ARM proper but by the OS itself once stood up. However the good thing is, you can use the vehicle/medium of an ARM template to specify these configuration changes. One could also use PowerShell DSC OR Azure DSC OR Azure platform Custom Script Extension (or Chef, Puppet or Ansible) to do this.

Following are some useful links on this topic.

As mentioned the script itself can be part of the template. Execution happens on the VM and not at the ARM layer.
Some additional references:-

  1. Custom Script Extension Schema (Windows)
  2. Custom Script Extension Schema (Linux)
  3. Template based deployment of Script extensions (Windows)
  4. Template based deployment of Script extensions (Linux)

There is also another technique where the sequence of commands you needed to be executed can be put inside an inline variable as below and then refer to this variable as the content of the configuration that needs to be done on the VM coming up and logging in the first time.

 "<FirstLogonCommands> 
  <SynchronousCommand> 
     <Order>1</Order> 
       <Description>Create diskpart input file</Description> 
      <CommandLine> powershell.exe -Command Write-Output \"select disk 2 ' create partition primary ' format quick ' assign \" | Out-File C:\\diskpart.txt 
     </CommandLine> 
   </SynchronousCommand> 
    <SynchronousCommand> 
     <Order>2</Order> 
       <Description>Create formatted partition</Description> 
      <CommandLine>diskpart.exe /s C:\\diskpart.txt
     </CommandLine>
    </SynchronousCommand> 
</FirstLogonCommands>"

 

In the above fragment we are specifying two commands to be executed in an order. The first one creates the file, whose contents are used/fed to the second command - in this case the disk partition utility - diskpart.exe. These commands are synchronous in nature as opposed to being async, so that order of execution is preserved.

 

Putting all of this together, the following is an example of using two inline variables

(a) unattendAutoLogonXML and

(b) unattendFirstRunXML which are then passed to the WindowsConfiguration to be executed on VM boot.

 

 

  "variables": {
"unattendAutoLogonXML":"[concat('<AutoLogon><Password><Value>',parameters('adminPassword'),'</Value></Password><Domain></Domain><Enabled>true</Enabled><LogonCount>1</LogonCount><Username>',parameters('adminUsername'),'</Username></AutoLogon>')]",

    "unattendFirstRunXML":"<FirstLogonCommands><SynchronousCommand><CommandLine>powershell.exe -Command Write-Output \"select disk 0 ' select partition 1 ' extend\" | Out-File C:\\diskpart.txt</CommandLine><Description>Create diskpart input file</Description><Order>1</Order></SynchronousCommand><SynchronousCommand><CommandLine>diskpart.exe /s C:\\diskpart.txt</CommandLine><Description>Extend partition</Description><Order>2</Order></SynchronousCommand></FirstLogonCommands>",

...
...
...  

      "osProfile": {

         "computerName": "[variables('vmName')]",

          "adminUsername": "[parameters('adminUsername')]",

          "adminPassword": "[parameters('adminPassword')]",

          "windowsConfiguration": {

             "additionalUnattendContent": [

               {

                    "passName": "oobeSystem",

                    "componentName": "Microsoft-Windows-Shell-Setup",

                    "settingName": "AutoLogon",

                    "content": "[variables('unattendAutoLogonXML')]"

                },

                {

                    "passName": "oobeSystem",

                    "componentName": "Microsoft-Windows-Shell-Setup",

                    "settingName": "FirstLogonCommands",

                    "content": "[variables('unattendFirstRunXML')]"

                }

            ]

          }