I built the following scripts to automate provisioning and initial configuration of Rocky Linux 9 containers on Proxmox VE 8.0.3.
Here is the build script:
Here is the script that it sent to the container and executed to update it:
Here is the CSV file called by the initial build script:
NOTES:
I am open to suggestions on how to improve this; I am no scripting expert. My goal is to be able to completely rebuilt and reconfigure my entire lab via a script. The above is the start; however, my plan is to also automate the installation and configuration of services (i.e.- BIND, DHCP, Docker, K3s, etc.) on select containers. I have a long way to go.
Eventually, I would love to convert this to an Ansible playbook, and maybe, even leverage APIs as opposed to the command line. Any feedback and/or help is appreciated. Thank you!
Here is the build script:
#!/bin/bash
# Load secrets
source /root/deploy_scripts/secrets/secrets.sh
# Set CSV input file of hostnames with IP addresses
input_file=hosts.csv
# Set variables for contain configuration
CORES=2
MEM=4096
SWAP=2048
GW=172.16.77.1
DNS=172.16.77.2
DOMAIN=lab.aftshock.com
HD=16
BRIDGE=vmbr0
# Get hostnames and IPs from CSV input file
tail -n +2 "$input_file" | while IFS=, read -r NAME IP _
do
# Get next available container ID
CT_ID=$(pvesh get /cluster/nextid)
# Build new container
echo "Building new container"
pct create $CT_ID local:vztmpl/rockylinux-9-default_20221109_amd64.tar.xz \
--cores $CORES \
--hostname $NAME \
--memory $MEM \
--swap $SWAP \
--net0 name=eth0,bridge=$BRIDGE,firewall=1,gw=$GW,ip=$IP/24,ip6=auto,type=veth \
--searchdomain $DOMAIN \
--nameserver $DNS \
--storage local-lvm \
--rootfs local-lvm:$HD \
--unprivileged 1 \
--features nesting=1 \
--ostype centos \
--arch amd64 \
--password $ROOT_PASS \
--ssh-public-keys /root/deploy_scripts/secrets/aftsvc.pub
# Add shared mount from Proxmox host
pct set $CT_ID -mp0 /mnt/shared1,mp=/mnt/shared1
# Start the container
pct start $CT_ID
# Copy files to container for initial OS configuration and updates
pct push $CT_ID /root/deploy_scripts/rocky-std-init-cfg.sh /root/rocky-std-init-cfg.sh
# Execute the chmod command inside the LXC to make .sh files exc
pct exec $CT_ID chmod +x /root/rocky-std-init-cfg.sh
# Execute the rocky-std-init-cfg.sh file inside the LXC
pct exec $CT_ID /root/rocky-std-init-cfg.sh
done
Here is the script that it sent to the container and executed to update it:
#!/bin/bash
# Update all packages
dnf upgrade -y --refresh
# Install dnf configuration manager
dnf install -y dnf-utils &&
# Install helpful tools
dnf install -y ca-certificates curl git nano ncurses openssh-server tar tmux unzip wget &&
# Enable SSH server
systemctl enable sshd --now &&
# Install automatic update tools
dnf install -y binutils binutils-gold dnf-automatic
# Add Webmin repo
cat << EOF > /etc/yum.repos.d/webmin.repo
[Webmin]
name=Webmin Distribution Neutral
mirrorlist=https://download.webmin.com/download/yum/mirrorlist
enabled=1
gpgkey=http://www.webmin.com/jcameron-key.asc
EOF
# Add EPEL repos
dnf config-manager --set-enabled crb
dnf install -y \
https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \
https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm &&
# Update all packages
dnf upgrade -y --refresh &&
# Install additional tools
dnf install -y cockpit openssl perl perl-Encode-Detect perl-IO-Tty perl-Net-SSLeay perl-Time-HiRes &&
# Install webmin
dnf install -y webmin &&
# Cleanup
rm /root/rocky-std-init-cfg.sh
# Reboot
reboot
Here is the CSV file called by the initial build script:
Hostname,IP
host1,10.10.1.5
host1,10.10.1.6
NOTES:
I am open to suggestions on how to improve this; I am no scripting expert. My goal is to be able to completely rebuilt and reconfigure my entire lab via a script. The above is the start; however, my plan is to also automate the installation and configuration of services (i.e.- BIND, DHCP, Docker, K3s, etc.) on select containers. I have a long way to go.
Eventually, I would love to convert this to an Ansible playbook, and maybe, even leverage APIs as opposed to the command line. Any feedback and/or help is appreciated. Thank you!
Last edited: