Search code examples
rubyshellvagrantdevops

Vagrant Shell Provision Script Runs Twice


I am trying to spin up 3 VMs from the same Vagrant Base Box. However, only 2 VMs get created. This is due to the fact that the shell provisioner script gets executed twice during the provisioning of the second VM. As a result the process is terminated with the errors detailed below.

Here is my Vagrantfile:

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

#The box name and the URL to Retrieve the Vagrant Box from
  config.vm.box = "eFx-Dev"
  config.vm.box_url = "http://web/provisioning/vagrant-boxes/centos7-basev0.1.box"
  config.ssh.insert_key = false


#Creating the first Dev Machine
#With network address being assigned via DHCP
#and bootstraped via a shell script.
#This script can be unique for each machine.
#But at the moment they are bootstarpped the same.
#The spects of the machine.
#Can be adjusted based on requirements.
  config.vm.define "eFxDev1" do |eFxDev1|
        eFxDev1.vm.hostname = "eFxDev1"
        eFxDev1.vm.box = "eFx-Dev"
        config.vm.network "public_network", type: "dhcp"
        config.vm.provision "shell", path: "vmscripts/bootstrap.sh"
        config.vm.provider "virtualbox" do |vb|
                vb.name = "eFx-Dev1"
                vb.memory = "10124"
                vb.customize ["modifyvm", :id, "--cpus", 4]
  end
end

  config.vm.define "eFxDev2" do |eFxDev2|
        eFxDev2.vm.hostname = "eFxDev2"
        eFxDev2.vm.box = "eFx-Dev"
        config.vm.network "public_network", type: "dhcp"
        config.vm.provision "shell", path: "vmscripts/bootstrap.sh"
        config.vm.provider "virtualbox" do |vb|
                vb.name = "eFx-Dev2"
                vb.memory = "10124"
                vb.customize ["modifyvm", :id, "--cpus", 4]
  end
end

  config.vm.define "eFxDev3" do |eFxDev3|
        eFxDev3.vm.hostname = "eFxDev3"
        eFxDev3.vm.box = "eFx-Dev"
        config.vm.network "public_network", type: "dhcp"
        config.vm.provision "shell", path: "vmscripts/bootstrap.sh"
        config.vm.provider "virtualbox" do |vb|
                vb.name = "eFx-Dev3"
                vb.memory = "10124"
                vb.customize ["modifyvm", :id, "--cpus", 4]
  end
 end
end

The first VM gets deployed by running the provisioner shell ONCE. The VM Boots up and Vagrant moves on to create the second VM:

==> eFxDev1: Importing base box 'eFx-Dev'...
==> eFxDev1: Matching MAC address for NAT networking...
...
==> eFxDev1: Running provisioner: shell...
    eFxDev1: Running: /tmp/vagrant-shell20170201-60595-wpa6qn.sh
==> eFxDev1: + yum install dos2unix -y --disableplugin=fastestmirror
==> eFxDev1: + sudo groupadd Efx
==> eFxDev1: groupadd: group 'Efx' already exists
...

The Second VM is deployed but for some reason runs the provisioner script TWICE and fails:

==> eFxDev2: Importing base box 'eFx-Dev'...
==> eFxDev2: Matching MAC address for NAT networking...
...
==> eFxDev2: Running provisioner: shell...
    eFxDev2: Running: /tmp/vagrant-shell20170201-60595-1fwit5t.sh
==> eFxDev2: + yum install dos2unix -y --disableplugin=fastestmirror
==> eFxDev2: + sudo groupadd Efx
==> eFxDev2: groupadd: group 'Efx' already exists
...
==> eFxDev2: Running provisioner: shell...
    eFxDev2: Running: /tmp/vagrant-shell20170201-60595-1mu7y6h.sh
==> eFxDev2: + yum install dos2unix -y --disableplugin=fastestmirror
==> eFxDev2: Nothing to do
==> eFxDev2: + sudo groupadd Efx
==> eFxDev2: groupadd: group 'Efx' already exists
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what

As a result the process fails and the third VM does not get provisioned. Why is the provision script run twice?


Solution

  • Its because you're mixing config and the specific machine variable.

    Any methods applied to config.vm will apply to ALL your machines (even if you put it in a specific machine block) so its better to put all your config.vm properties outside of any specific machine block, you could rewrite your script as

    Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    
    #The box name and the URL to Retrieve the Vagrant Box from
    config.vm.box = "eFx-Dev"
    config.vm.box_url = "http://web/provisioning/vagrant-boxes/centos7-basev0.1.box"
    config.ssh.insert_key = false
    config.vm.network "public_network", type: "dhcp"
    
    
    #Creating the first Dev Machine
    #With network address being assigned via DHCP
    #and bootstraped via a shell script.
    #This script can be unique for each machine.
    #But at the moment they are bootstarpped the same.
    #The spects of the machine.
    #Can be adjusted based on requirements.
    config.vm.define "eFxDev1" do |eFxDev1|
      eFxDev1.vm.hostname = "eFxDev1"
      eFxDev1.vm.provision "shell", path: "vmscripts/bootstrap.sh"
      eFxDev1.vm.provider "virtualbox" do |vb|
              vb.name = "eFx-Dev1"
              vb.memory = "10124"
              vb.customize ["modifyvm", :id, "--cpus", 4]
      end
    end
    
    config.vm.define "eFxDev2" do |eFxDev2|
      eFxDev2.vm.hostname = "eFxDev2"
      eFxDev2.vm.box = "eFx-Dev"
      eFxDev2.vm.provision "shell", path: "vmscripts/bootstrap.sh"
      eFxDev2.vm.provider "virtualbox" do |vb|
              vb.name = "eFx-Dev2"
              vb.memory = "10124"
              vb.customize ["modifyvm", :id, "--cpus", 4]
      end
    end
    
    config.vm.define "eFxDev3" do |eFxDev3|
      eFxDev3.vm.hostname = "eFxDev3"
      eFxDev3.vm.box = "eFx-Dev"
      eFxDev3.vm.provision "shell", path: "vmscripts/bootstrap.sh"
      eFxDev3.vm.provider "virtualbox" do |vb|
              vb.name = "eFx-Dev3"
              vb.memory = "10124"
              vb.customize ["modifyvm", :id, "--cpus", 4]
      end
     end
    end