Tuomas Toivonen Tuomas Toivonen - 1 month ago 9
Bash Question

How to keep vagrant configuration organized

I'm provisioning vagrant box with ansible. However, my vagrant host doesn't support ansible, so I must execute ansible against localhost from within the vagrant box. I'm using shell provisioner, executing a script which will install ansible and run the correct ansible command against a playbook in a synced folder.

This solution works, but feels messy and hard to maintain, as configuration data is cluttered between files. As you can see below, there is duplication of playbook path, hard coded both to Vagrantfile and provisioning script. And as we know, duplication is the source of evil. Rather, I would like to keep all configuration strings in Vagrantfile or external file. Is this possible in my case? It would be also nice to be able to override these values with command line parameters.

Here is the vagrant file

VAGRANT_API_VERSION = 2
BOX_IMAGE = "ubuntu/trusty64"
PROVISIONING_SRC = "./provisioning"
PROVISIONING_DEST = "/etc/provisioning/vagrant"

Vagrant.configure(VAGRANT_API_VERSION) do |config|

config.vm.box = BOX_IMAGE
config.vm.network "private_network", ip: "192.168.22.22"
config.vm.network "forwarded_port", guest: 8080, host: 8080
config.vm.network "forwarded_port", guest: 8081, host: 8081
config.vm.network "forwarded_port", guest: 2222, host: 2223
config.vm.network "forwarded_port", guest: 5000, host: 5000
config.vm.network "forwarded_port", guest: 50000, host: 50000
config.vm.provision :shell, path: "provisioning.sh"

config.vm.synced_folder "./provisioning", "/etc/provisioning/vagrant"

end


Here is the provisioning script

apt-get install -y python-pip
apt-get install -y git-core

if [ -z $PLAYBOOK_PATH ]; then
echo "PLAYBOOK_PATH not set, using default"
PLAYBOOK_PATH=/etc/provisioning/vagrant/playbook.yml
fi

if [ -n $PLAYBOOK_PATH ]; then
echo "PLAYBOOK_PATH set at $PLAYBOOK_PATH"

if [ -f $PLAYBOOK_PATH ]; then
echo "PLAYBOOK FOUND, insalling ansible and starting provisioning"
pip install ansible
pip install markupsafe

if ( ansible-playbook $PLAYBOOK_PATH ); then
echo "provisioning OK"
else
echo "prvosioning failed"
fi

else
echo "PLAYBOOK not found"
fi

else
echo "PLAYBOOK_PATH not set"
fi


And finally here is the playbook inside provisioning folder

- name: Provision local docker host
hosts: localhost
become : yes
roles:
- docker.ubuntu
tasks:
- name: Add vagrant to docker group
become: yes
user: name=vagrant groups=docker append=yes

Answer

You dont necessarily need to do all this.

Vagrant supports running ansible on the guest VM aka ansible local

The Vagrant Ansible Local provisioner allows you to provision the guest using Ansible playbooks by executing ansible-playbook directly on the guest machine.

You can have a Vagrantfile like

VAGRANT_API_VERSION = 2
BOX_IMAGE = "ubuntu/trusty64"
PROVISIONING_SRC = "./provisioning"
PROVISIONING_DEST = "/etc/provisioning/vagrant"

Vagrant.configure(VAGRANT_API_VERSION) do |config|

  config.vm.box = BOX_IMAGE
  config.vm.network "private_network", ip: "192.168.22.22"
  config.vm.network "forwarded_port", guest: 8080, host: 8080
  config.vm.network "forwarded_port", guest: 8081, host: 8081
  config.vm.network "forwarded_port", guest: 2222, host: 2223
  config.vm.network "forwarded_port", guest: 5000, host: 5000
  config.vm.network "forwarded_port", guest: 50000, host: 50000

  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "provisioning/playbook.yml"
  end

end