Cloud-Init and Hostnames
First problem was Ubuntu 20.04 to properly boot from the Packer HTTP directory. I found approximately 3,125,319 blogs online all with different Ubuntu boot commands. I settled on this:
boot_command = [
"c",
"linux /casper/vmlinuz --- autoinstall ds=\"nocloud-net;seedfrom=http://{{.HTTPIP}}:{{.HTTPPort}}/\"",
"<enter><wait>",
"initrd /casper/initrd",
"<enter><wait>",
"boot<enter>"
]
Next up was a working user-data
file for the boot customisation process. I settled on a mish-mash of different examples found online:
#cloud-config
autoinstall:
version: 1
early-commands:
# Stop ssh for packer
- sudo systemctl stop ssh
locale: en_US
keyboard:
layout: en
variant: us
# general packages needed for machines - referenced from https://tekanaid.com/posts/hashicorp-packer-build-ubuntu20-04-vmware
packages: [open-vm-tools, openssh-server, cloud-init]
# network setup - referenced from https://tekanaid.com/posts/hashicorp-packer-build-ubuntu20-04-vmware
identity:
hostname: ubuntu-tmpl
username: ubuntu
password: '$6$rounds=4096$M7sE5MB76OAGlRVL$cB7KGUsihonBTndSGBkfsdN0EzIDBeuY6ENt3kRuazSEJZhqRxeSaC.5/E4KRksGdOTRPA8sXWlpRSlUUrXVo1'
ssh:
install-server: yes
allow-pw: yes
storage:
layout:
name: lvm
apt:
primary:
- arches: [i386, amd64]
uri: "http://archive.ubuntu.com/ubuntu/"
user-data:
disable_root: false
timezone: UTC
late-commands:
- sed -i -e 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /target/etc/ssh/sshd_config
- echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/ubuntu
- curtin in-target --target=/target -- chmod 440 /etc/sudoers.d/ubuntu
Pay careful attention to the default user and password that is created. The password should be generated using sha-512 with 4096 rounds. Command was mkpasswd --method=sha-512 --rounds=4096 <password>
. The password in this example was VMware1!
.
After cloud-init is finished, I would have a “prep” script run to clean everything up, ready for template time:
#!/bin/bash
echo '> Cleaning all audit logs ...'
if [ -f /var/log/audit/audit.log ]; then
cat /dev/null > /var/log/audit/audit.log
fi
if [ -f /var/log/wtmp ]; then
cat /dev/null > /var/log/wtmp
fi
if [ -f /var/log/lastlog ]; then
cat /dev/null > /var/log/lastlog
fi
# Cleans SSH keys.
echo '> Cleaning SSH keys ...'
rm -f /etc/ssh/ssh_host_*
# Sets hostname to localhost.
echo '> Setting hostname to localhost ...'
cat /dev/null > /etc/hostname
hostnamectl set-hostname localhost
# Cleans apt-get.
echo '> Cleaning apt-get ...'
apt-get clean
# Cleans the machine-id.
echo '> Cleaning the machine-id ...'
truncate -s 0 /etc/machine-id
rm /var/lib/dbus/machine-id
ln -s /etc/machine-id /var/lib/dbus/machine-id
# Reset the machine-id value. This has known to cause issues with DHCP
#
truncate -s 0 /etc/machine-id
rm /var/lib/dbus/machine-id
ln -s /etc/machine-id /var/lib/dbus/machine-id
# Reset any existing cloud-init state
#
echo "Resetting Cloud-Init"
rm /etc/cloud/cloud.cfg.d/*.cfg
cloud-init clean -s -l
Once Packer is finished, you’ll end up with a VM template in vSphere. Go to vRealize Automation and rescan for images in the Cloud Accoount that contains this new template.
Here’s my first stumble. Deploying a VM from this template with a cloud-config
specification would never be customised. No matter what I tried, it just didn’t work and not even something as basic as the hostname was being set. I found a boat load of blogs recommending I install the custom VMware Guest Info plugin for Cloud Init by running this installation script during the template build. Well, I tried that and still had no luck. I tried using dpkg-reconfigure cloud-init
to specify OVF and VMware Guest Info as the the data source for cloud-init but had no luck there either as it was interactive and I couldn’t find a headless command to run it.
It wasn’t until a few days passed and many template builds later that I had a good look at the VMware Guest Info README. The install script repo for the VMware Data source had been archived! This caught my eye:
This datasource has been merged into cloud-init as DataSourceVMware
Right, I think that’s it! I added a quick line to my prep script:
# Adding VMware Data Source
echo 'datasource_list: [ "DataSourceVMware", "OVF" ]' > /etc/cloud/cloud.cfg.d/00-ovf-data.cfg
Re-ran the build and tested it in vRA. Yep, hostname is now being set! Let’s move on.
vRA-defined user not being set in vRA deployment
vRA supports Cloud-Init customisation of guests using Cloud-Init on Linux and Cloudbase-Init for Windows. With my new template now customising the hostname, I noticed the default ubuntu
account was being reset and I couldn’t log in with the password. Looking at the deployment, vRA was pushing the following cloud-init config:
#cloud-config
hostname: u20
No config was being pushed for the default ubuntu
user. Found on the docs here: https://cloudinit.readthedocs.io/en/latest/topics/examples.html#including-users-and-groups that in order to reset the default user, typically ubuntu
on a fresh install, you need to add this code to your cloud-init:
#cloud-config
hostname: u20-2
system_info:
default_user:
name: ubuntu
plain_text_passwd: ((secret:v1:AAHTS2SZncwnv3EGYDhbz9Q8w812JKePvy1l2zrPJFmIHLMyr3/h8g==))
home: /home/ubuntu
shell: /bin/bash
lock_passwd: false
If you specify a remoteAccess
user that differs to the ubuntu
account, vRA will try to push another user as the default:
#cloud-config
hostname: u20-2
system_info:
default_user:
name: ubuntu
plain_text_passwd: ((secret:v1:AAHTS2SZncwnv3EGYDhbz9Q8w812JKePvy1l2zrPJFmIHLMyr3/h8g==))
home: /home/ubuntu
shell: /bin/bash
lock_passwd: false
users:
- default
- name: stell
lock_passwd: false
ssh_pwauth: true
passwd: ((secret:v1:AAGgzY4Hjbqux3HW/PXJjXbycZ3UiWH62EfgdfCELzaZ3KQCNTvPTA==))
runcmd:
- sudo sed -i -e '/^PasswordAuthentication/s/^.*$/PasswordAuthentication yes/' /etc/ssh/sshd_config
- sudo sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin yes/' /etc/ssh/sshd_config
- sudo service sshd restart
In the above example, my cloud-config was the hostname and system_info > default_user config, and the remoteAccess configuration from the Cloud Template was parsed and added under the users
block. Note: The remoteAccess user specified will passed to Salt Stack Config to connect to the guest and install the Salt Minion, so make sure you’re giving it the right access.
That’s pretty much it! Sorry for the rushed writing, these are notes more for myself than anything.
- Restore of a Wordpress deployment is stuck redirecting the port
- Backups and Restores using Velero in TKGm 1.6.1
- Unable to upgrade the database: org.postgresql.util.PSQLException: ERROR: could not open shared memory segment: No such file or directory
- Upgrading Cloud Director 10.4.1 to 10.5
- Installing and Configuring Velero in TKGm 1.6.1 on vSphere