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