3 Replies Latest reply on Feb 26, 2019 4:17 AM by raptorirl

    Swapping new VM template for current one by renaming new template to production name (without updating blueprints etc)?

    HerbMartin Lurker

      Is it possible to swap a new VM template for the current one without updating blueprints etc.?

       

      Goal:  Update and test new machine, convert to template, swap by renaming during CRQ window (off hours) without muss or fuss.

       

      Currently:  Our team is taking the current templates offline to update and convert back because they apparently had problem with swapping.

      [My guess was that vRA is using some ID number and not the name which prevented our folks from doing it by swapping (renaming).]

       

      I know little of vRA but wanted to prep the new template and just swap them over quickly on a Saturday or late night.

       

      Actually, I know so little of vRA that likely the above wording is mangled so feel free to correct but basically, I want to avoid having to do all the "changes", updating and testing during the CRQ window.  Pre-build the replacement, test it, then swap it in simply and only test that vRA can still build (not that the OS image stuff is right.)

       

      Please try to answer as asked but if there is a better way to think about that please ALSO include that.

       

      And also if you can point me to where to RTFM I don't necessarily need a step by step, just enough to figure it out....

       

      --

      HerbM

        • 1. Re: Swapping new VM template for current one by renaming new template to production name (without updating blueprints etc)?
          jasnyder Expert
          vExpert

          I don't know the answer to this, but taking a quick look at some things, I think it might be possible to swap the UUIDs of the two templates to make this work.

           

          Assuming you're on at least vRA 7.2...

           

          The vRA appliance database stores the blueprint component with a reference to the virtual machine template or base VM and snapshot.  The reference is an entity reference to the IaaS entity that backs the component.  For example:

          {"type":"entityRef","componentId":null,"classId":"Infrastructure.Virtual.Schema","id":"712f6130-dfbe-4d7a-8741-dee1d4dbd906","label":"vra72_RHEL7_linkedClone_Base"}

           

          The ID listed there is the VirtualMachineID from the IaaS database inventory of vSphere machines that have been data collected from the vCenter endpoints.  That ID lives within the IaaS system.  But stored with the VM is a reference to the VM's unique ID (InstanceUUID) from the inventory.  I have played with swapping InstanceUUIDs on provisioned machines before, and if the system cannot find a VM with the InstanceUUID it's expecting, it will post a status of "Missing."  If you swap InstanceUUIDs back it will find the VM again after data collection.  So I assume the same trick would work in this case.  But I also know that with each VM is an ExternalReferenceID, which is the managed object reference of the VM in the vCenter inventory.  This is only unique within a single vCenter and could be duplicated in a different vCenter.  So I believe the managed object ID field would get updated as a result of searching the inventory for the specified InstanceUUID.

           

          In order to update the InstanceUUID of 2 machines, you would need to take the original and change it's InstanceUUID to an interim ID, change the new template's InstanceUUID to the original's, and then change the original's to the new one's or leave it at whatever.

           

          For example:

           

          original-template.InstanceUUID = UUID-Temp

          new-template.InstanceUUID = UUID-Original

          original-template.Instance.UUID = UUID-New

           

          This is to avoid trying to set multiple machines with the same InstanceUUID.

           

          You can change the InstanceUUID using the API or PowerShell.  Here is a script I previously used to change MAC and InstanceUUID (only changes on or both if they are both specified, so you can omit the MAC parameter to leave MAC unchanged).

           

          Note that the UUID used here is InstanceUUID vs. UUID or BIOS UUID.

          Param(

              [string]$vmName,

              [string]$newMac,

              [string]$newUUID

          )

           

          $queryOnly = $false

          $vm = Get-View -ViewType VirtualMachine -Filter @{"Name" = $vmName}

          $conf = $vm.config

           

          $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

          $changedSomething = $false

           

          Write-Output $vm

           

          #Block to set MAC address on virtual device spec; only do it if newMac is not empty

          if($newMac -ne "")

          {

              $netDevice = New-Object VMware.Vim.VirtualDevice

              foreach($dev in $conf.hardware.device)

              {

                  #Write-Output($dev.deviceInfo.label + " - " + $dev.deviceInfo.summary)

           

                  if($dev.deviceInfo.label -eq "Network adapter 1")

                  {

                      $currentMac = $dev.macAddress;

                     

                      Write-Output("Current ethernet0 MAC: " + $currentMac)

                      $netDevice = $dev

                  }

                 

              }

             

              Write-Output("Setting new MAC: " + $newMac)

              $newDeviceConfigSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec

              $netDevice.macAddress = $newMac

              $newDeviceConfigSpec.device = $netDevice;

              $newDeviceConfigSpec.operation = 2 #1 = add 2 = edit 3 = remove

              #New-Object VMware.Vim.VirtualDeviceConfigSpecOperation

              #$newDeviceConfigSpec = $newDeviceConfigSpec.fromString("edit")

           

              $spec.deviceChange = $newDeviceConfigSpec

           

              $changedSomething = $true;

             

          }

           

          #Block to set UUID on config spec; only do it if newUIID is not empty

           

          if($newUUID -ne "")

          {

              if($vm.summary.runtime.powerState.poweredOn)

              {

                  Write-Output("TODO: Power Off Machine First");

              }

              Write-Output("Current UUID: " + $conf.InstanceUUID);

              Write-Output("Setting new UUID: " + $newUUID);

           

              $spec.InstanceUUID = $newUUID;

           

              $changedSomething = $true;

           

          }

           

          #Update the machine config spec only if queryOnly = false and something above was supplied for change (i.e. newMac != "" || newUUID != "")

           

          if(!$queryOnly -and $changedSomething)

          {

              Write-Output("Committing changes");

              $vm.reconfigVM_Task($spec);

              Write-Output(" complete");

          }

           

          You can run this with:

          changeUUIDandMac.ps1' -vmName MBG1-73 -newUUID 501e40e9-d4ef-83e4-0d81-805444945105

           

          You can get the InstanceUUID of a VM in inventory with:

          Write-Output (get-vm <vm_name>).ExtensionData.Config.InstanceUUID

           

          So you would want to collect the original UUIDs first, and replace them with a script later.  If you encounter any problems, return the UUIDs back to their original state without making any other changes and initiate a data collection.

           

          Once you make the change, you need to data collect inventory on the compute resource for it to get recognized by vRA.

           

          Also note that the VMs should be powered off when making the change (obvious since they're templates, but just saying...)

           

          As I said before, I haven't tested this in your specific use case, but I think there's a decent chance it would work.  If you decide to test it, please be sure to use it in a test environment, or at least create a new blueprint to test with thoroughly before hacking up your production environment.

          1 person found this helpful
          • 2. Re: Swapping new VM template for current one by renaming new template to production name (without updating blueprints etc)?
            HerbMartin Lurker

            Thx.  More involved that I hoped and expected but straightforward enough with your code that I should be able to do it.

            • 3. Re: Swapping new VM template for current one by renaming new template to production name (without updating blueprints etc)?
              raptorirl Novice
              maybe a bit late :-) , just seen this when searching for something else. It's quite straight forward. Include the property CloneFrom within your blueprint, where the value is the template name,. This overrides the UUID of the originally selected template.