Warning: This article fails to follow some security best practices and is not meant for enterprise use.
In this post a CentOS 7 VM will be set up on Proxmox. That VM will then be converted to a template and exemplarily deployed.
A VM with the desired hardware parameters has to be created. The option
Qemu Agent should be set to
A minimal installation image can be used to get a really clean template. The installation options should be set according to the targeted environment. A fitting hostname can be used but is not necessary. Having network time services correctly set up can be crucial for a lot of applications. Setting a static IP instead of using DHCP can cause conflicts when deploying multiple VMs at once or in future.
The root password should be stored securely as this will be the initial password of all deployed VMs. Optionally a default (sudo) user could be created so root login could be disabled in the next step.
It is possible to disable IPv6 at this point. As this template is intended for testing purposes, firewalld and selinux will be disabled as well.
echo "net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6=1" >> /etc/sysctl.conf systemctl disable firewalld sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
Now the packages need to be updated and any packages that should be installed by default on future machines need to be installed. This should include the qemu-guest-agent.
yum update --skip-broken -y yum install epel-release -y yum install htop tmux qemu-guest-agent -y
To lower the maintenance effort, yum-cron can be set up to keep the packages updated. A production environment should be limited to only security updates. This installation will keep the default (installing all updates).
yum install yum-cron -y sed -i 's/download_updates = no/download_updates = yes/g' /etc/yum/yum-cron.conf sed -i 's/apply_updates = no/apply_updates = yes/g' /etc/yum/yum-cron.conf systemctl enable yum-cron
Any other individual default configuration needs to be done now.
The system now has to be cleaned of any logs, unique identifiers, keys and old kernels. This part can be put inside a shell script.
/sbin/service rsyslog stop /sbin/service auditd stop /bin/package-cleanup --oldkernels --count=1 /usr/bin/yum clean all /usr/sbin/logrotate -f /etc/logrotate.conf /bin/rm -f /var/log/*-???????? /var/log/*.gz /bin/rm -f /var/log/dmesg.old /bin/rm -rf /var/log/anaconda /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 /bin/rm -f /etc/machine-id /bin/rm -f /etc/udev/rules.d/70* /bin/sed -i '/^(HWADDR|UUID)=/d' /etc/sysconfig/network-scripts/ifcfg-e* /bin/rm -rf /tmp/* /bin/rm -rf /var/tmp/* /bin/rm -f /etc/ssh/*key* /bin/rm -f ~root/.bash_history unset HISTFILE /bin/rm -rf ~root/.ssh/ /bin/rm -f ~root/anaconda-ks.cfg
To finally clear the history and let CentOS do the last bits, the following has to be executed interactively. The system will shut down on execution.
history -c sys-unconfig
Convert to template
To make this VM a template, the context menu option
Convert to template has to be used. That’s all.
To deploy a new VM form a template, the
Clone option has to be used. After powering on the VM it’s IP should be visible on the Proxmox interface thanks to the qemu-guest-agent. At this point logging in via SSH should be possible and the configuration can be finalized by resetting the root password, configuring a static DHCP lease (or setting a static IP for the VM manually) and applying the new hostname.
passwd hostnamectl set-hostname <new-hostname> && systemctl reboot