After some testing I now have a complete setup for interacting Packer with vSphere.
My parameters here are for testing hence the small disk, tiny kickstart etc. Use it as your base for further enhancements/testing.
This setup has been tested on a CentOS 6.5 Server. The eth1toeth0.sh script is not needed for Redhat/CentOS 5.X installations. The variables part are passed to the Linux Boot Menu i.e. by pressing [TAB].
I am using Python’s integrated HTTP Server:
python -m SimpleHTTPServer
I start the http server in my home dir:
/Users/TheDude
My Build/Source Directory:
/Users/TheDude/Build/{scripts,kickstart}
My ISO Directory is:
/Users/TheDude/packer/{ISO}
VMware Tools package recovered from a Linux box by mounting the VMware Tools DVD.
Use headless mode depending if you want to see VMware installation running. Good for debugging!
Launching the build/validate process
Validate JSON:
RockSolid:~ TheDude$ packer validate templateCOS6.json
Std:
RockSolid:~ TheDude$ packer build templateCOS6.json
Ex. VARIABLES
RockSolid:~ TheDude$ packer build -var "myhost=MyOtherCentOS" -var "myip=192.168.198.120" templateCOS6.json
Ex. VARIABLES With Logging:
RockSolid:~ TheDude$ PACKER_LOG=1 packer build -var "myhost=MyOtherCentOS" -var "myip=192.168.198.120" templateCOS6.json
StartHTTP.sh Script:
#!/bin/sh
python -m SimpleHTTPServer
Output from Terminal:
RockSolid:~ TheDude$ ./StartHTTP.sh
Serving HTTP on 0.0.0.0 port 8000 ...
vCenter JSON:
{
"variables": {
"remote_host": "192.168.198.50",
"myhost": "rhdev100",
"mydomain": "rocksolid.com",
"myip": "192.168.198.29",
"mygw": "192.168.198.2",
"mymask": "255.255.255.0",
"mydns1": "192.168.198.2",
"mydns2": "192.168.198.3",
"mydatastore": "NFS_DATASTORE_01"
},
"builders": [
{
"boot_command": [
"<tab>",
"vmlinuz initrd=initrd.img ",
"myhostname={{user `myhost`}} ",
"mydomain={{user `mydomain`}} ",
"myip={{user `myip`}} ",
"mygateway={{user `mygw`}} ",
"mynetmask={{user `mymask`}} ",
"mydns1={{user `mydns1`}} ",
"mydns2={{user `mydns2`}} ",
"ks=http://192.168.198.1:8000/Build/kickstart/rh.cfg <enter><wait>"
],
"boot_wait": "5s",
"disk_size": 4098,
"guest_os_type": "rhel6-64",
"headless": false,
"http_directory": "http",
"iso_checksum": "32c7695b97f7dcd1f59a77a71f64f2957dddf738",
"iso_checksum_type": "sha1",
"iso_url": "http://192.168.198.1:8000/packer/ISO/CentOS-6.5-x86_64-bin-DVD1.iso",
"output_directory": "{{user `myhost`}}",
"name": "rhel6-64",
"shutdown_command": "shutdown -h now",
"skip_compaction": false,
"ssh_password": "SecretPasswd",
"ssh_port": 22,
"ssh_username": "root",
"ssh_wait_timeout": "10000s",
"tools_upload_flavor": "linux",
"type": "vmware-iso",
"vmx_data": {
"ethernet0.networkName": "VM Network",
"ethernet0.present": "TRUE",
"ethernet0.virtualDev": "vmxnet3",
"cpuid.coresPerSocket": "1",
"memsize": "512",
"numvcpus": "1",
"scsi0:0.fileName": "disk.vmdk",
"scsi0:0.present": "TRUE",
"scsi0:0.redo": ""
}
}
],
"provisioners": [
{
"type": "file",
"source": "/Users/TheDude/Build/VMware/VMwareTools-9.6.1-1378637.tar.gz",
"destination": "/tmp/VMwareTools-9.6.1-1378637.tar.gz"
},
{
"execute_command": "echo 'TheDude' | {{.Vars}} sudo -S -E bash '{{.Path}}'",
"scripts": [
"scripts/yum.sh",
"scripts/sysctl.sh",
"scripts/vmtools.sh",
"scripts/network.sh",
"scripts/eth1toeth0.sh"
],
"type": "shell"
}
],
"post-processors": [
{
"type": "vsphere",
"host": "vc01.rocksolid.com",
"username": "TheDude",
"password": "SecretPasswd",
"datacenter": "DC01",
"cluster": "Lab",
"resource_pool": " ",
"datastore": "{{user `mydatastore`}}",
"vm_folder": "CentOS",
"vm_name": "{{user `myhost`}}",
"vm_network": "VM Network",
"insecure" : "true"
}
]
}
rh.cfg Script:
##########################################################
# RHEL6.X Kickstart Example Small
##########################################################
text
install
cdrom
network --bootproto=dhcp
# US Lang/Keyb
lang en_US.UTF-8
keyboard us
# Mots de pass root
rootpw MySecretPassword
# Disable Firewall
firewall --disabled
# Disable SELinux
selinux --disabled
# Authentication
authconfig --enableshadow --enablemd5
timezone --utc Europe/Paris
# Disk stuff!
bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"
# ZAP the disk before using.
zerombr yes
clearpart --drives=sda --initlabel
part /boot --fstype ext4 --size=500
part pv.008034 --size=1 --grow
volgroup VolGroup00 --pesize=4096 pv.008034
logvol / --fstype ext4 --name=lv_root --vgname=VolGroup00 --grow --size=1024
logvol swap --fstype swap --name=lv_swap --vgname=VolGroup00 --size=1024 --grow --maxsize=1024
# Reboot Server and finish Packer
reboot
# Packages (Minimal for testing only)
%packages
@Base
@Core
openssh-server
sudo
########################################################
# Post Configuration -nochroot environment
########################################################
# Add Log
%post --nochroot --log=/mnt/sysimage/root/my-post-log
# Extract variables from Boot Menu
CMDLINE_FILE=/proc/cmdline
THIS_HOSTNAME=$(cat ${CMDLINE_FILE} | grep myhostname | sed -e 's/.*myhostname=\([^ ]*\).*/\1/')
THIS_DOMAIN=$(cat ${CMDLINE_FILE} | grep mydomain | sed -e 's/.*mydomain=\([^ ]*\).*/\1/')
THIS_IPADDR=$(cat ${CMDLINE_FILE} | grep myip | sed -e 's/.*myip=\([^ ]*\).*/\1/')
THIS_NETMASK=$(cat ${CMDLINE_FILE} | grep mynetmask | sed -e 's/.*mynetmask=\([^ ]*\).*/\1/')
THIS_GATEWAY=$(cat ${CMDLINE_FILE} | grep mygateway | sed -e 's/.*mygateway=\([^ ]*\).*/\1/')
THIS_DNS_1=$(cat ${CMDLINE_FILE} | grep mydns1 | sed -e 's/.*mydns1=\([^ ]*\).*/\1/')
THIS_DNS_2=$(cat ${CMDLINE_FILE} | grep mydns2 | sed -e 's/.*mydns2=\([^ ]*\).*/\1/')
# Saving variables from Boot Menu -> /root/network.params.txt"
RH_INSTALL_LOG=/mnt/sysimage/root/network.params.txt
echo "myhostname ${THIS_HOSTNAME}" >> ${RH_INSTALL_LOG}
echo "mydomain ${THIS_DOMAIN}" >> ${RH_INSTALL_LOG}
echo "myip ${THIS_IPADDR}" >> ${RH_INSTALL_LOG}
echo "mygateway ${THIS_GATEWAY}" >> ${RH_INSTALL_LOG}
echo "mynetmask ${THIS_NETMASK}" >> ${RH_INSTALL_LOG}
echo "mydns1 ${THIS_DNS_1}" >> ${RH_INSTALL_LOG}
echo "mydns2 ${THIS_DNS_2}" >> ${RH_INSTALL_LOG}
########################################################
# Post Configuration chroot environment
########################################################
%post
echo "Disabling useless services if enabled!"
# Disable rhnsd daemon
/sbin/chkconfig rhnsd off
/sbin/chkconfig rhsmcertd off
# Disable yum-updatesd daemon
/sbin/chkconfig yum-updatesd off
# Disable smartd daemon
/sbin/chkconfig smartd off
# Disable iptables daemon
/sbin/chkconfig ip6tables off
/sbin/chkconfig iptables off
# Disable wpa_supplicant
/sbin/chkconfig wpa_supplicant off
# Disable sendmail
/sbin/chkconfig sendmail off
# Enable postfix
/sbin/chkconfig postfix off
# Disable bluetooth
/sbin/chkconfig bluetooth off
# Disable SNMP
/sbin/chkconfig snmpd off
/sbin/chkconfig snmptrapd off
# Enable NTP
/sbin/chkconfig ntpd on
# Disable PC/SC Smartcard
/sbin/chkconfig pcscd off
# Enable/Disable Portmap
/sbin/chkconfig portmap off
# Disable other useless services
/sbin/chkconfig atd
/sbin/chkconfig lm_sensors off
/sbin/chkconfig mdmonitor off
/sbin/chkconfig mcstrans off
/sbin/chkconfig xinetd off
/sbin/chkconfig gpm off
/sbin/chkconfig isdn off
/sbin/chkconfig iscsi off
/sbin/chkconfig iscsid off
/sbin/chkconfig pcmcia off
/sbin/chkconfig cups off
/sbin/chkconfig hidd off
/sbin/chkconfig anacron off
/sbin/chkconfig avahi-daemon off
/sbin/chkconfig cpuspeed off
/sbin/chkconfig kudzu off
/sbin/chkconfig rpcgssd off
/sbin/chkconfig rpcidmapd off
yum.sh Script:
#!/bin/bash -eux
########################################################
# Post Configuration
########################################################
function addPkgs() {
echo "Update packages + Security packages"
# Update with more packages & update security packages
yum -y -q install openssh*
yum -y -q install openssl*
yum -y -q install net-snmp
yum -y -q install ntp
yum -y -q install vim-common
yum -y -q install vim-enhanced
yum -y -q install nfs-utils
yum -y update --security
}
function addUser() {
echo "Adding Local User => TheDude"
# Add Local User => TheDude
/usr/sbin/useradd TheDude
echo "SecretPasswd" | passwd --stdin TheDude
# sudo
echo "TheDude ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers
}
setupPasswd() {
echo "Removing entries from /etc/passwd file"
sed -i '/news/d' /etc/passwd
sed -i '/operator/d' /etc/passwd
sed -i '/games/d' /etc/passwd
sed -i '/gopher/d' /etc/passwd
sed -i '/ftp/d' /etc/passwd
}
setupNtp() {
(cat <<- EOF
########################
# Local /etc/ntp.conf
########################
# Line for Virtual Machines
tinker panic 0
restrict 127.0.0.1
restrict default kod nomodify notrap
# Use PHM servers.
server 0.centos.pool.ntp.org
server 1.centos.pool.ntp.org
server 2.centos.pool.ntp.org
driftfile /var/lib/ntp/drift
keys /etc/ntp/keys
EOF
) > /etc/ntp.conf
}
########################################################
# Run the Functions
########################################################
addUser
setupPasswd
setupNtp
addPkgs
sysctl.sh Script:
#!/bin/bash -eux
setupKern() {
(cat <<- EOF
# Kernel sysctl configuration file for Red Hat Linux
# Suitable for dedicated web server, mail, ftp server etc.
# ---------------------------------------
# BOOLEAN Values:
# a) 0 (zero) - disabled / no / false
# b) Non zero - enabled / yes / true
# --------------------------------------
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename
# Useful for debugging multi-threaded applications
kernel.core_uses_pid = 1
# Controls the use of TCP syncookies
#net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2
########## IPv4 networking start ##############
# Send redirects, if router, but this is just server
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Accept packets with SRR option? No
net.ipv4.conf.all.accept_source_route = 0
# Accept Redirects? No, this is not router
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
# Log packets with impossible addresses to kernel log? yes
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Ignore all ICMP ECHO and TIMESTAMP requests sent to it via broadcast/multicast
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Prevent against the common 'syn flood attack'
net.ipv4.tcp_syncookies = 1
# Enable source validation by reversed path, as specified in RFC1812
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
########## IPv6 networking start ##############
# Number of Router Solicitations to send until assuming no routers are present.
# This is host and not router
net.ipv6.conf.default.router_solicitations = 0
# Accept Router Preference in RA?
net.ipv6.conf.default.accept_ra_rtr_pref = 0
# Learn Prefix Information in Router Advertisement
net.ipv6.conf.default.accept_ra_pinfo = 0
# Setting controls whether the system will accept Hop Limit settings from a router advertisement
net.ipv6.conf.default.accept_ra_defrtr = 0
#router advertisements can cause the system to assign a global unicast address to an interface
net.ipv6.conf.default.autoconf = 0
#how many neighbor solicitations to send out per address?
net.ipv6.conf.default.dad_transmits = 0
# How many global unicast IPv6 addresses can be assigned to each interface?
net.ipv6.conf.default.max_addresses = 1
########## IPv6 networking ends ##############
#Enable ExecShield protection
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# TCP and memory optimization
# increase TCP max buffer size setable using setsockopt()
#net.ipv4.tcp_rmem = 4096 87380 8388608
#net.ipv4.tcp_wmem = 4096 87380 8388608
# increase Linux auto tuning TCP buffer limits
#net.core.rmem_max = 8388608
#net.core.wmem_max = 8388608
#net.core.netdev_max_backlog = 5000
#net.ipv4.tcp_window_scaling = 1
# increase system file descriptor limit
fs.file-max = 65535
#Allow for more PIDs
kernel.pid_max = 65536
#Increase system IP port limits
net.ipv4.ip_local_port_range = 2000 65000
EOF
) > /etc/sysctl.conf
}
# Run Function
setupKern
vmtools.sh Script:
#!/bin/bash -eux
# Install VMware Tools
cd /tmp
tar zxvf /tmp/VMwareTools-*.tar.gz -C /tmp
/tmp/vmware-tools-distrib/vmware-install.pl --default
network.sh Script:
#!/bin/bash -eux
# Get the parameters saved from Boot Menu and apply to our new VM
CMDLINE_FILE=/root/network.params.txt
THIS_HOSTNAME=$(cat ${CMDLINE_FILE} | grep myhostname | awk '{print $2}')
THIS_DOMAIN=$(cat ${CMDLINE_FILE} | grep mydomain | awk '{print $2}')
THIS_IPADDR=$(cat ${CMDLINE_FILE} | grep myip | awk '{print $2}')
THIS_NETMASK=$(cat ${CMDLINE_FILE} | grep mynetmask | awk '{print $2}')
THIS_GATEWAY=$(cat ${CMDLINE_FILE} | grep mygateway | awk '{print $2}')
THIS_DNS_1=$(cat ${CMDLINE_FILE} | grep mydns1 | awk '{print $2}')
THIS_DNS_2=$(cat ${CMDLINE_FILE} | grep mydns2 | awk '{print $2}')
echo -e "\tNetwork Interface Setup (eth0)"
(cat <<- EOF
DEVICE=eth0
BOOTPROTO=static
IPADDR=${THIS_IPADDR}
NETMASK=${THIS_NETMASK}
ONBOOT=yes
EOF
) > /etc/sysconfig/network-scripts/ifcfg-eth0
/bin/chmod 644 /etc/sysconfig/network-scripts/ifcfg-eth0
(cat <<- EOF
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=${THIS_HOSTNAME}
GATEWAY=${THIS_GATEWAY}
EOF
) > /etc/sysconfig/network
/bin/chmod 644 /etc/sysconfig/network
# DNS
# Check if we have 2 DNS Servers
if [ -z "${THIS_DNS_2}" ] ; then
(cat <<- EOF
search $THIS_DOMAIN
nameserver ${THIS_DNS_1}
EOF
) > /etc/resolv.conf
else
(cat <<- EOF
search $THIS_DOMAIN
nameserver ${THIS_DNS_1}
nameserver ${THIS_DNS_2}
EOF
) > /etc/resolv.conf
fi
# /etc/hosts
(cat <<- EOF
${THIS_IPADDR} ${THIS_HOSTNAME}.${THIS_DOMAIN} ${THIS_HOSTNAME}
EOF
) >> /etc/hosts
eth1toeth0.sh Script:
#!/bin/bash -eux
# Remove 70-persistent-net.rules and create eth0 during next boot
cp /etc/udev/rules.d/70-persistent-net.rules /var/tmp/70-persistent-net.rules
rm -f /etc/udev/rules.d/70-persistent-net.rules