terraform-provider-vsphere icon indicating copy to clipboard operation
terraform-provider-vsphere copied to clipboard

`r/virtual_machine`: add support for serial port(s)

Open aj-cruz opened this issue 4 years ago • 8 comments

Description

Requesting a new property for the vsphere_virtual_machine resource to add a serial port to a VM. Network appliances such as Cisco's Nexus 9000v switch have the ability to redirect a network-backed (or named pipes) virtual serial port to the VMs console and is used quite heavily in lab scenarios.

Potential Terraform Configuration

resource "vsphere_virtual_machine" "TF-DC1-SPINE-SWITCH" {
  ......configuration......
  serial_port {
    backing_type: "network"
    direction: "server"
    service_uri: "telnet://<ip>:<port>"
    yield_on_poll: true
  }
}

References

#540

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

aj-cruz avatar Sep 21 '21 20:09 aj-cruz

when importing an OVA specifying a serial-port (in the .OVF-file) as required hardware, like here

      <ovf:Item ovf:required="false">
        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
        <rasd:Description>Console Port</rasd:Description>
        <rasd:ElementName>Serial 1</rasd:ElementName>
        <rasd:InstanceID>6</rasd:InstanceID>
        <rasd:ResourceType>21</rasd:ResourceType>
      </ovf:Item>

this information is ignored, too.

heitmanr avatar Nov 14 '21 12:11 heitmanr

I'd like to add, that an empty "<ip>"-Address is absolutely fine for vCenter/ESXi allowing, so this should be allowed, too:

serial_port {
    backing_type: "network"
    direction: "server"
    service_uri: "telnet://:<port>"
    yield_on_poll: true
  }

This is an example copied from a running vm/vmx-file:

serial0.fileType = "network"
serial0.fileName = "telnet://:23901"
serial0.yieldOnMsrRead = "TRUE"
serial0.present = "TRUE"

heitmanr avatar Nov 14 '21 12:11 heitmanr

right now, i'm using this as a workaround, call it an ugly hack ;-)

Terraform creates VMs called (Cisco Nexus 9000v)-VMs, called "LEAF-A" and so on, afterwards Terraform uses PowerShell/PowerCLI to add the missing Serial-Port - the VM won't boot without it.

# locals {
#   switches = {
#     "LEAF-A" = { serial_port="23931" },
#     "LEAF-B" = { serial_port="23932" },
#     "SPINE-A" = { serial_port="23951" },
#     "SPINE-B" = { serial_port="23952" },
#   }
#   }

  resource "null_resource" "PowerShellScriptRunFirstTimeOnly" {
    for_each = local.switches

    triggers = {
      trigger = "${vsphere_virtual_machine.n9k[each.key].uuid}"
    }
    provisioner "local-exec" {

        #credits
        #http://access-console-port-virtual-machine.blogspot.com/2013/07/add-serial-port-to-vm-through-gui-or.html
        #https://kevsoft.net/2019/04/26/multi-line-powershell-in-terraform.html
        #https://markgossa.blogspot.com/2019/04/run-powershell-from-terraform.html?m=1
        command = <<EOPS

          Function New-SerialPort {
             Param(
               [string]$vmName,
               [string]$prt
             )
            $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
            $dev.operation = "add"
            $dev.device = New-Object VMware.Vim.VirtualSerialPort
            $dev.device.key = -1
            $dev.device.backing = New-Object VMware.Vim.VirtualSerialPortURIBackingInfo
            $dev.device.backing.direction = "server"
            $dev.device.backing.serviceURI = "telnet://:$prt"
            $dev.device.connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo
            $dev.device.connectable.connected = $true
            $dev.device.connectable.StartConnected = $true
            $dev.device.yieldOnPoll = $true

            $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
            $spec.DeviceChange += $dev

            $vm = Get-VM -Name $vmName
            Stop-VM $VM -Confirm:$False
            $vm.ExtensionData.ReconfigVM($spec)
            Start-VM $VM -Confirm:$False
          }

          Connect-VIServer -Server ${var.vsphere_server} -User ${var.vsphere_username} -Password ${var.vsphere_password}
          New-SerialPort ${each.key} ${each.value.serial_port}
          Disconnect-VIServer -Confirm:$false
        EOPS
        interpreter = ["PowerShell", "-Command"]
    }

}

heitmanr avatar Nov 17 '21 15:11 heitmanr

I don't think it's an ugly hack. It's a good use of the provisioner to fill a gap in resource creation capability.

Ryan

tenthirtyam avatar Nov 17 '21 16:11 tenthirtyam

@heitmanr I like it, thanks

aj-cruz avatar Nov 17 '21 17:11 aj-cruz

We make quite extensive use of Virtual Serial Port Concentrator (vSPC), so adding a serial port to any VM is essential for us.

Unfortunately this is currently not supported by the vsphere provider. Are there plans to change this anytime soon, and add support for serial ports ?

devnull-mr avatar Apr 25 '23 20:04 devnull-mr

I know this sucks as a workaround, but assuming you don't have many different ovf/ova:

  1. create a VM from the ova/ovf
  2. don't boot it so it's virgin
  3. add the serial port

create the VM from a clone, like instead of

ovf_deploy {
 ...
}

use:

clone {
  template_uuid = ....
}

I can't imagine this is a big lift to add this to the resource, but probably not a huge priority either.

EDIT: actually this will use the same file for all VMs.. may not be ideal.

mritalian avatar Sep 06 '23 13:09 mritalian