Script to create VMWare Node
This is a bash script to create a new vmware node (ESX). It uses Ansible (along with python pysphere) to create a node from a template. I originally use Cobbler to provision nodes and used Ansible to create a bare vmware node, but the provisioning time was around 15 to 20 minutes, too long for my needs. Cloning from a template made for a provision time of around 5 minutes, reasonable but not stellar. Once the node is created, a remote session is opened (via vmware tools) to configure network settings & trigger a reboot. Once rebooted, the node runs puppet agent to finalize configuration.
See also: node-update, node-update-ubuntu
=========================================================================================================================================================================
#! /bin/bash
# vi:set nu ai ap aw smd showmatch tabstop=4 shiftwidth=4:
# get program name
PNAME=$(basename $0)
# hardcode our some of our network params
NETMASK=255.255.252.0
GATEWAY=10.2.204.1
# utility to get mac address of a vmware node
getmac="/etc/ansible/playbooks/getmac"
# error handler
function Die() {
echo "$*"
logger -t $PNAME "$*"
exit 1
}
# usage help
function usage() {
echo "Usage of ${PNAME}"
echo ""
echo "Short Options:"
echo "${PNAME} [-h] [-f fqdn] [-r role] [-e environment] [-p puppetmaster-FQDN]"
echo ""
echo "Long Options:"
echo "${PNAME} [--help] [--fqdn FQDN] [--role ROLE] [--env ENV] [--puppet puppetmaster-FQDN]"
echo ""
echo " -h display help usage"
echo " -f fqdn specify FQDN of new virtual node"
echo " -r role specify role of new virtual node (default: none) [jenkins-master,jenkins-slave,coverity,artifactory,sonarqube,puppetmaster,general]"
echo " -e environment specify environment (default: devops_services_test)"
echo " -p puppetmaster specify FQDN of puppetmaster (default: puppet-mss.qalabs.symantec.com)"
echo ""
exit 0
}
# declare options
if ! options=$(getopt -o hf:r:e:p: --long help,fqdn:,role:,env:,puppet: -n "$PNAME" -- "$@")
then
usage
exit 1
fi
# collect options
eval set -- "$options"
# set initial options
# we default the ENV and PUPPET
# if the user doesn't specify role & fqdn, we fail.
ENV="devops_services_test"
PUPPET="puppet-mss.qalabs.symantec.com"
# process options
while [ $# -gt 0 ]
do
case $1 in
-h|--help) usage; exit1;;
-f|--fqdn) FQDN="$2"; shift;;
-r|--role) ROLE="$2"; shift;;
-e|--env) ENV="$2"; shift;;
-p|--puppet) PUPPET="$2"; shift;;
(--) shift; break;;
(-*) usage; exit 1;;
(*) usage; exit 1;;
esac
shift
done
# validate options ...
if [ "${FQDN}X" = "X" ]
then echo "Must specify FQDN"
usage
exit 1
fi
# validate the FQDN
host $FQDN > /dev/null 2>&1 || Die "Invalid FQDN, $FQDN"
# validate the ROLE
if [ "${ROLE}X" = "X" ]
then echo "Must specify ROLE"
echo "Valid roles are: jenkins-master, jenkins-slave, coverity, sonarqube, artifactory, puppetmaster, general"
usage
exit 1
fi
# define the ansible playbook
case $ROLE in
"jenkins-master") ansfile="/etc/ansible/playbooks/cent67-8g4c250.yml";;
"jenkins-slave") ansfile="/etc/ansible/playbooks/cent67-8g4c250.yml";;
"coverity") ansfile="/etc/ansible/playbooks/cent67-8g2c250.yml";;
"artifactory") ansfile="/etc/ansible/playbooks/cent67-8g2c250.yml";;
"sonarqube") ansfile="/etc/ansible/playbooks/cent67-2g1c50.yml";;
"general") ansfile="/etc/ansible/playbooks/cent67-2g1c50.yml";;
"puppetmaster") ansfile="/etc/ansible/playbooks/ubuntu-4g1c50.yml";;
*) echo "Invalid ROLE, $ROLE"; usage;;
esac
echo ">>> creating service $ROLE on address $FQDN"
# create the vmware node
ansible-playbook $ansfile --extra-vars "fqdn=$FQDN"
# wait for node to get created
echo ">>> waiting for node to get created to extract mac address"
until $getmac $FQDN
do
sleep 5
done
# get the mac
mac=$($getmac $FQDN | awk '{print $2}')
echo ">>> mac: $mac"
# get the ipaddress
ipaddress=$(host $FQDN | awk '{print $NF}')
# power node on
echo ">>> powering system on"
ansible-playbook /etc/ansible/playbooks/vm-on.yml --extra-vars "fqdn=$FQDN"
echo ">>> node $FQDN is powering up"
## check if cent is in template
if echo $ansfile | grep cent > /dev/null
then
# build centos network interface file
echo "NETWORKING=yes
HOSTNAME=$FQDN
" > /tmp/${FQDN}-network
echo "DEVICE=eth0
ONBOOT=yes
TYPE=Ethernet
BOOTPROTO=none
IPADDR=$ipaddress
NETMASK=$NETMASK
DNS1=10.2.204.2
GATEWAY=$GATEWAY
IPV6INIT=no
USERCTL=no
" > /tmp/${FQDN}-ifcfg-eth0
else
## we're building ubuntu
echo "
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
address $ipaddress
netmask $NETMASK
gateway $GATEWAY
dns-nameservers 10.2.204.2
dns-search qalabs.symantec.com
" > /tmp/${FQDN}-interfaces
fi
echo "${FQDN%%.*}" > /tmp/${FQDN}-hostname
echo "$ROLE" > /tmp/${FQDN}-role
echo "$ENV" > /tmp/${FQDN}-env
## update puppet.conf for client environment
sed "s/ENVIRONMENT/${ENV}/g" /usr/local/bin/puppet.conf.template > /tmp/${FQDN}-puppet.conf
## update puppet.conf for client puppetmaster
sed -i "s/PUPPETMASTER/$PUPPET/g" /tmp/${FQDN}-puppet.conf
## check if cent
if echo $ansfile | grep cent > /dev/null
then
## update remote node (call python program)
echo ">>> remotely updating $FQDN"
node-update $FQDN
else
## otherwise ubuntu
node-update-ubuntu $FQDN
fi
## wait for node to reboot & power up
echo ">>> waiting for node to come up"
until ping -c 1 $FQDN > /dev/null
do
sleep 10
done
sleep 10
if echo $ROLE | grep puppetmaster > /dev/null
then
ssh -oStrictHostKeyChecking=no $FQDN apt-get -y install puppetmaster-passenger
else
# trigger remote puppet run
echo ">>> ssh to $host to trigger puppet run"
ssh -oStrictHostKeyChecking=no $FQDN puppet agent -t
fi
# trigger remote reboot
echo ">>> rebooting $host"
ssh -oStrictHostKeyChecking=no $FQDN reboot now
# wait for finish
echo ">>>> ALL DONE!!!!!"
exit 0