Configuring a vsphere template image securely

Hello everyone,

I am somewhat new to the Hashicorp ecosystem, but I have spent a few weeks playing around with Terraform. Now, I am trying to make a template to deploy with Terraform on our vsphere cluster using Packer. I have successfully managed to make a CentOS10-stream image using a kickstart file and some scripts for hardening, but I haven’t figured out a way to remove the user that Packer uses to configure the machine. And since this user has full sudo rights, this is obviously a security issue. I have tried to remove the user, but, as expected, this kicks out Packer while it is configuring. Does anyone here know of a way to either
A) delete a user at the end of the configuration process (before it is packaged into a template using the vsphere convert_to_template option),
B) set up a temporary user to avoid possible shenanigans altogether, or
C) somehow put a trusted public key onto the image before it fully boots so that the SSH connection that Packer uses can be done using a key rather than a password?

I can provide my code if necessary, but I’m unsure if it is needed to answer the question. Either way, thank you in advance for any tips, advice, or examples that you are willing to share :slight_smile:

1 Like

Totally valid concern! Here’s a quick breakdown:

A) Add a cleanup script as a final Packer provisioner (like shell with pause_before) to delete the user after all provisioning is done but before the image is finalized.
B) Yes, you can use a temporary user—just ensure it’s created early and removed in that final cleanup step.
C) You can preload your public SSH key via the kickstart %post section or a Packer file provisioner early in the build, then set "ssh_private_key_file" in your Packer config to avoid using passwords altogether.

1 Like

Apologies, I forgot to get back to you. Option C is the one that worked for me. Specifically, in my %post section, I simply parse my public key into the authorized_keys file:

# in kickstart_file_template.cfg
# Commands run after configuration but before the first reboot
%post
## Set trusted public key for the created user
mkdir -p /home/${username}/.ssh/
echo "${pubkey}" > /home/${username}/.ssh/authorized_keys
# more stuff
%end

I use the templatefile() function to bring the necessary data into the file:

# in main.pkr.hcl, source "vsphere-iso" "centos10" {}
  # Boot configuration
  ##cd_content is used to load the user data onto a virtual CDROM
  cd_content                  = {
    "/ks.cfg"  = templatefile(
      "${path.root}/config/kickstart_file_template.cfg", {
        username              = var.ssh_username
        password              = data.password.random_password.crypt
        host_name             = var.vm_host_name
        pubkey                = file("${var.ci_project_dir}/${var.ssh_pubkey}")
      }
    )
  }

The kickstart file is brought onto the VM template using the following boot configuration:

# in main.pkr.hcl, source "vsphere-iso" "centos10" {}
  boot_command                = ["<up>e", "<down><down><end>", " text inst.ks=cdrom", "<enter><wait><leftCtrlOn>x<leftCtrlOff>"]

And finally, closer to the top we have the configuration to securely connect to the temporary virtual machine through an ssh-key, without ever needing to log in through a password.

  # Communicator settings
  communicator                = "ssh"
  ssh_username                = var.ssh_username
  ssh_private_key_file        = "${var.ci_project_dir}/${var.ssh_privkey}"

Thank you for the tips! I hope someone else can use this in the future :slight_smile:

1 Like