Background
For a while now I have been struggling with Packer templates built with Ubuntu 20.04 server deployed on VSphere 7.0. When I build the packer image and deploy VM’s with terraform specifying a static IP with terraforms customize block, DHCP would pick up an additional IP address as well as the static IP.
I found that the issue stemmed from packer requiring dhcp assignment for the post deploy ssh shell provisioner. To solve this issue a few lines of code were added to the provisioner to:
- Remove netplan config
- Remove dhcp from grub file
- Update grub
- Purge cloud-init
Code
I have included the .hcl code below, after building this template, all terraform provisioned vm’s off this template will only have the static IPs assigned via the customize block.
| source “vsphere-iso” “this” { | |
| vcenter_server = var.vsphere_server | |
| username = var.vsphere_user | |
| password = var.vsphere_password | |
| datacenter = var.datacenter | |
| cluster = var.cluster | |
| insecure_connection = true | |
| vm_name = “tf-ubuntu-server-20.04” | |
| guest_os_type = “ubuntu64Guest” | |
| ssh_username = “ubuntu” | |
| ssh_password = “ubuntu” | |
| ssh_timeout = “20m” | |
| ssh_handshake_attempts = “50” | |
| CPUs = 8 | |
| RAM = 4128 | |
| RAM_reserve_all = true | |
| disk_controller_type = [“pvscsi”] | |
| datastore = var.datastore | |
| storage { | |
| disk_size = 16384 | |
| disk_thin_provisioned = true | |
| } | |
| iso_paths = [“[iSCSI Raid-10] OS/ubuntu-20.04.2-live-server-amd64.iso”] | |
| iso_checksum = “sha256:b23488689e16cad7a269eb2d3a3bf725d3457ee6b0868e00c8762d3816e25848” | |
| http_directory = “subiquity/http” | |
| http_port_max = 8336 | |
| http_port_min = 8336 | |
| network_adapters { | |
| network = var.network_name | |
| network_card = “vmxnet3” | |
| } | |
| boot_wait = “5s” | |
| boot_command = [ | |
| ” “, | |
| “autoinstall net.ifnames=0 biosdevname=0 ip=dhcp ipv6.disable=1 ds=nocloud-net;seedfrom=http://192.168.0.168:{{ .HTTPPort }}/”, | |
| “” | |
| ] | |
| } | |
| build { | |
| sources = [ | |
| “source.vsphere-iso.this” | |
| ] | |
| provisioner “shell” { | |
| inline = [ | |
| “while [ ! -f /var/lib/cloud/instance/boot-finished ]; do sleep 5; done”, | |
| “sudo rm /etc/netplan/*”, | |
| “sudo sed -i ‘s/ip=dhcp//g’ /etc/default/grub”, | |
| “sudo update-grub”, | |
| “sudo apt -y purge cloud-init” | |
| ] | |
| } | |
| } |
I have also include a sample main.tf below:
| provider "vsphere" { | |
| vsphere_server = var.vsphere_server | |
| user = var.vsphere_user | |
| password = var.vsphere_password | |
| # If you have a self-signed cert | |
| allow_unverified_ssl = true | |
| } | |
| data "vsphere_datacenter" "dc" { | |
| name = var.datacenter | |
| } | |
| data "vsphere_resource_pool" "pool" { | |
| name = var.resourcepool | |
| datacenter_id = data.vsphere_datacenter.dc.id | |
| } | |
| data "vsphere_datastore" "datastore" { | |
| name = var.datastore | |
| datacenter_id = data.vsphere_datacenter.dc.id | |
| } | |
| data "vsphere_network" "network" { | |
| name = var.network_name | |
| datacenter_id = data.vsphere_datacenter.dc.id | |
| } | |
| data "vsphere_virtual_machine" "ubuntu" { | |
| name = var.ubuntu_name | |
| datacenter_id = data.vsphere_datacenter.dc.id | |
| } | |
| resource "vsphere_virtual_machine" "k8Master1-0" { | |
| name = "k8Master1-0" | |
| resource_pool_id = data.vsphere_resource_pool.pool.id | |
| datastore_id = data.vsphere_datastore.datastore.id | |
| network_interface { | |
| network_id = data.vsphere_network.network.id | |
| adapter_type = "vmxnet3" | |
| } | |
| num_cpus = 4 | |
| memory = 4128 | |
| wait_for_guest_net_timeout = 0 | |
| wait_for_guest_ip_timeout = 0 | |
| disk { | |
| label = "disk0" | |
| thin_provisioned = true | |
| size = 16 | |
| } | |
| guest_id = "ubuntu64Guest" | |
| clone { | |
| template_uuid = data.vsphere_virtual_machine.ubuntu.id | |
| customize { | |
| network_interface { | |
| ipv4_address = "192.168.0.208" | |
| ipv4_netmask = 24 | |
| } | |
| ipv4_gateway = "192.168.0.1" | |
| linux_options { | |
| host_name = "k8Master1-0" | |
| } | |
| } | |
| } | |
| } |
I hope this quick write up help anyone with this issue. It took me quite a bit of researching and was unable to find a single solution. I wished that a resource such as this one was available so I decided to make it.