Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control multi-machine Vagrant block execution order

I have a Multi-machine vagrant setup with some blocks which I need to change the execution order for.

Due to the vagrant order being outside-in the most nested block executes last.

I need a way to make the provision blocks more nested so they execute last. I have tried adding mach.vm.define but those blocks don't execute and I don't understand why.

Normal Execution, wrong order

Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"

require 'yaml'

machines = YAML.load_file('vagrant.yaml')

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  machines.each do |machine|

    config.vm.define machine["name"] do |mach|

      machine['run_this'].each do |run_this|
        mach.vm.provider "virtualbox" do |v, override|
          # should run first
        end
      end

      # Do a puppet provision to install the rest of the software
      mach.vm.provision "puppet" do |puppet|
        # puppet stuff
      end

      mach.vm.box = 'ubuntu/trusty64'

  end
end

Ideal solution but extra nested block doesn't execute

Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"

require 'yaml'

machines = YAML.load_file('vagrant.yaml')

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  machines.each do |machine|

    config.vm.define machine["name"] do |mach|

      machine['run_this'].each do |run_this|
        mach.vm.provider "virtualbox" do |v, override|
          # should run first but it doesn't because it's in an extra provider block
        end
      end

      mach.vm.define :prov do |prov| # This block doesn't execute

        # Do a puppet provision to install the rest of the software
        prov.vm.provision "puppet" do |puppet|
          # puppet stuff
        end

      end

      mach.vm.box = 'ubuntu/trusty64'

    end
  end
end

Is there a way to make the provisioning one level deeper so it runs after the content of the provider block?

EDIT: Anything which is provider specific is not acceptable (for example, another provider block) or anything which causes duplicate code.

like image 692
Sam Avatar asked Aug 25 '15 12:08

Sam


1 Answers

I don't know what exactly you're doing on the first block so that's why I'm assuming that it can be inverted with the inner block (the one that interacts with :run_this attribute).

With this little change we can put all the execution blocks on the same level. Bellow you'll find the code that I've tried to simulate your problem.

Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"

require "yaml"

machines = YAML.load_file("vagrant.yml")

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  machines.each do |machine|

    config.vm.define machine["name"] do |mach|

      mach.vm.box = "ubuntu/trusty64"
      mach.vm.provision :shell, inline: "echo A"

      mach.vm.provider :virtualbox do |v, override|

        v.name = machine["name"]
        override.vm.provision :shell, inline: "echo B"

        machine["run_this"].each do |run_this|
          override.vm.provision :shell, inline: "echo C"
        end

        # puppet stuff should come here (all on the same level)
        override.vm.provision :shell, inline: "echo D"

      end

    end

  end

end
like image 176
warantesbr Avatar answered Sep 28 '22 18:09

warantesbr