hashicorp / terraform-provider-vsphere

Terraform Provider for VMware vSphere
https://registry.terraform.io/providers/hashicorp/vsphere/
Mozilla Public License 2.0
611 stars 450 forks source link

Add support for serial port(s) to `vsphere_virtual_machine` #1481

Open aj-cruz opened 2 years ago

aj-cruz commented 2 years ago

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

heitmanr commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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"]
    }

}
tenthirtyam commented 2 years ago

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

aj-cruz commented 2 years ago

@heitmanr I like it, thanks

devnull-mr commented 1 year ago

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 ?

mritalian commented 1 year ago

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.

aj-cruz commented 2 months ago

Still yearning for this capability. For the past years I've been using govc with a provisioner as a workaround, but recently I started deploying linux VMs with a serial port for console access to the VM, and when I use the provisioner it breaks customization (IP address and hostnames don't get configured via CloudInit). I'm guessing because the provisioner is powering down the VM to add the serial port.

The reason I need the console even though I'm deploying IP information is because my use case is for deploying labs. I'm using vsphere_virtual_machine to create lab topologies that have no IP connectivity to my outside network. The IP information in the Linux customization is all internal to the lab, so the serial port or the vSphere console are my only ways to remotely access the lab VMs