Vagrant for Bash Scripting

Creating a bash script to provision a Vagrant Virtual Machine

Chase Putnam

3 minute read

Coming from a background in systems administration as well as software development, when I first found out about the Vagrant Virtual Machine configuration platform Vagrant by HashiCorp, instead of going toward also learing a new build/configuration management system for Os level configurations and software installation, like Ansible, Chef, or Puppet, I instead first thought about seeing how easy it could be to migrate some local development machine bash configuration scripts to being used with Vagrant.

Running a Bash Script from a VagantFile

Vagrant has a specific section in the VagrantFile examples about how to initiate shell commands or execute shell scripts in the default vagrant folder location.

For my Linux distro of choice, I use CentOS, with the latest as of this writting as CentOS7.

CentOS 7 disables pure password authentication for SSH access which proves cumbersome for an environment solely used for local development or testing purposes, so we need to enable password authentication and restart the ssh daemon once the OS is booted.

sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config

CentOS 7 also comes with full SE (Secure Enforcement) Linux configurations in place by defaut which can make scripted installations difficut, so we first need to disable SE Linux using:

sudo setenforce 0

After those configurations are in place, we can run any other commands or scripts to perform base installation activities. Here I set the hostname of the server and also pipe the output of the installation script messaging to a log file in case any issues are encountered using the tee command.

The final shell section of the Vagrant file could look something like mine below:

config.vm.provision "shell", inline: <<-SHELL
sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
sudo systemctl restart sshd
sudo setenforce 0
sudo hostname vagrant.dev.local
cd /vagrant
dvar=$(date -u +"20%y-%m-%d_%H_%M")
sh bootstrapBaseInstallCentOS.sh 2>&1 | tee -a bootstrap.log.$dvar
SHELL

The Installation Script

The bash script should attempt to install and configure whatever sub-systems your software depends on to run as well as perform the compilation/installation of your software and any post-install configurations.

To capture some default messaging should the installation script fail, I typically use echo to output specific details followed by a default message for next steps.

uncleanExitMessage="Please run 'vagrant destroy' to delete your current VM that is in an inconsistent state before running 'vagrant up' again.\n"

Since I mostly develop in Java, my installation script attempts to automatically retrieve the latest release of Oracle Java 8, install it, and also install Apache ANT.

Java:

#!/bin/bash
#Install Java
if (( $(echo "$version > 1.2" | bc -l) ));then
  echo -e "VAGRANT_INSTALLER: Installing Java 8..."
  javaUrl=$(curl "http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html" | grep "linux-x64.rpm" | grep "jdk" | awk -F ',' '{print $3}' | awk -F '\":\"' '{print $2}' | sed 's/.$//' | awk -F ' ' '{print $1}' | head -1)
  java
  curl -v -j -k -L -O -H "Cookie: oraclelicense=accept-securebackup-cookie" "$javaUrl"
  sudo rpm -ivh jdk-* --force
else
  echo -e "VAGRANT_INSTALLER: Installing Java 7..."
  if [ -f /vagrant/installerJDK7/jdk-7u80-linux-x64.rpm ];then
    sudo rpm -ivh /vagrant/installerJDK7/jdk-7u80-linux-x64.rpm
  else
    echo -e "VAGRANT_INSTALLER: No JDK 7 installer RPM present... Exiting...\n"
    echo -e $uncleanExitMessage
    exit 1
  fi
fi
if [ $? != "0" ]; then
  echo -e "VAGRANT_INSTALLER: Error downloading or installing Java... Exiting..."
  echo -e $uncleanExitMessage
  exit 1
fi
echo "export JAVA_HOME=/usr/java/latest/" >> ~/.bashrc
echo -e "VAGRANT_INSTALLER: Java installed...\n"
exit

Apache ANT

#!/bin/bash
antVersion="apache-ant-1.9.10"
antUrl="http://archive.apache.org/dist/ant/binaries/$antVersion-bin.tar.gz"

#Install Ant
curl -O "$antUrl"
sudo tar -xzvf $antVersion-bin.tar.gz -C /usr/lib
if [ $? != "0" ]; then
echo -e "VAGRANT_INSTALLER: Error downloading or installing Ant... Exiting..."
echo -e $uncleanExitMessage
exit 1
fi
sudo update-alternatives --install /usr/bin/ant ant /usr/lib/$antVersion/bin/ant 0
echo "export ANT_HOME=/usr/bin/ant" >> ~/.bash_profile

rm -f apache-ant*
echo -e "VAGRANT_INSTALLER: Ant installed...\n"
exit

Once that is complete, you should have the beginnings of a bash script or scripts that can be used to configure and install base services on a new OS in Vagant.

comments powered by Disqus