When engineering some solutions for multi-cloud use cases I realised that the templates I have been using for vRA/SaltStack Config were designed for my on-prem vSphere environment and would not work on public cloud instances (excluding VMC). Hence, it is time for a template refresh!
My image defaults will probably be unique in small areas (e.g. hostname, NTP servers, disk partitioning) but the high-level steps are documented here. Feel free to adjust according to your needs.
This article will describe the process to create a cloud agnostic image for CentOS 7.9 to be deployed by vRA
Requirements
- Base Operating System with hardly any customisation – post-deployment customisation and software package installation should be performed by SaltStack Config
- Minimum OS packages common to most use cases
- Use cloud-init for Linux customisation
- Use the vRA IPAM to assign the static IP address
- Use vRA to assign a custom hostname
- Disable the OS firewall (as will be using NSX DFW)
Setup
- Create a new VM as per standard practice
- Create Virtual Hardware as follows:
- Latest vHW version supported by all ESXi hosts in the cluster, or native vHW from the public cloud
- 1 vCPU
- 2 GB RAM
- PVSCSI adaptor (or LSI Logic SAS)
- 30 GB HDD 1
- Thin Provision if supported by the datastore
- VMXNET3 network adaptor (or Intel E1000E)
- Connected to a network with DHCP
- EFI BIOS and Secure Boot options
- Mount the Latest version of CentOS 7 Server ISO to the CDROM
- Power on the VM and commence the OS installation
- Select NETWORK & HOST NAME
- Change hostname e.g. img-centos-79-ci
- Turn on the NIC Ethernet (ens192) and ensure you get an IP address from DHCP. Even though this image will be used with vRA static IP assignment, you need an initial IP address and Internet connection now to do OS updates and install base software

- Select DATE & TIME
- Define the Region and City
- Turn on Network Time and configure

- Select SOFTWARE SELECTION
- Choose Infrastructure Server with Directory Client and Guest Agents

- Select INSTALLATION DESTINATION
- Adjust the partitioning as desired. I am using Automatically configure partitioning

- Select Begin Installation
- Set the root user password. This should be duplicated in a vRA Secret named tmpl_admin_password (vRA Cloud Assembly / Infrastructure / Secrets)
- Once the OS has been installed, log into the hardware shell as the root user
- Apply OS updates: yum update -y
- Install and configure cloud-init: yum install -y cloud-init
- As I want to use static networking in my vRA blueprint and have the vRA IPAM assign the IP address, we need to make some changes to cloud-init to not mess with the dynamic specification created by vRA when using the static property in a blueprint. To do this:
vi /etc/cloud/cloud.cfg
disable_vmware_customization: true
Add a section:
network:
config: disabled
Also modify the options for the SSH service:
disable_root: 0
ssh_pwauth: 1

- Reboot the VM so you can now log in as root using SSH
- Install supplementary packages to join to Active Directory:
yum install -y realmd sssd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation authselect-compat - Disable the local firewall – I will be using NSX DFW
systemctl stop firewalld
systemctl disable firewalld
systemctl mask –now firewalld - Create a file /etc/seal.sh with the following contents:
#Stop the Logging Services
/sbin/service rsyslog stop
/sbin/service auditd stop
#Remove any old kernels
package-cleanup --oldkernels --count=1
#Clean out package manager cache
yum clean all
#Remove old logs we don’t need
/bin/rm -f /var/log/dmesg.old
/bin/rm -rf /var/log/anaconda
#Truncate the audit logs
/bin/cat /dev/null > /var/log/audit/audit.log
/bin/cat /dev/null > /var/log/wtmp
/bin/cat /dev/null > /var/log/lastlog
/bin/cat /dev/null > /var/log/grubby
#Remove the udev persistent device rules
/bin/rm -f /etc/udev/rules.d/70*
#Remove the traces of the template MAC address and UUIDs
/bin/sed -i '/^(HWADDR|UUID)=/d' /etc/sysconfig/network-scripts/ifcfg-e*
#Clean /tmp out
/bin/rm -rf -d /tmp/*
/bin/rm -rf -d /var/tmp/*
#Remove the SSH host keys
/bin/rm -f /etc/ssh/*key*
#Remove the root user’s shell history
/bin/rm -f ~root/.bash_history
unset HISTFILE
#Remove the root user’s SSH history and other stuff
/bin/rm -rf ~root/.ssh/
/bin/rm -f ~root/anaconda-ks.cfg
#Clean cloud-init settings
cloud-init clean
#Clear bash history and shutdown for template creation
history -c
sys-unconfig
- Set executable permissions: chmod 700 /etc/seal.sh
- Seal the VM before final shutdown and template creation
Conclusion
This refreshed image is now available to be used by VRA when targeting on-prem vSphere as well as public cloud providers. It forms the base image for a fully automated build process using vRA and SaltStack Config.