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