Vagrant execute script or command after every guest restart (vagrant up)

Just offering an alternative here that worked for me, using vagrant triggers. Consider this example straight from their docs:

Running a remote script to save a database on your host before destroying a guest:

Vagrant.configure("2") do |config|   
  config.vm.define "ubuntu" do |ubuntu|
    ubuntu.vm.box = "ubuntu"

    ubuntu.trigger.before :destroy do |trigger|
      trigger.warn = "Dumping database to /vagrant/outfile"
      trigger.run_remote = {inline: "pg_dump dbname > /vagrant/outfile"} 

      # or trigger.run = {...} to run the command on the host instead 
      # of guest
    end
  end 
end

There's also the related vagrant-triggers plugin you can check out


you can use run: 'always'

config.vm.provision :shell, path: "vagrant/bootstrap.sh", run: 'always'

This will make sure your command are executed every time your VM is starting (vagrant up or vagrant reload)

If you need only certain commands to be always run, you can split your script

config.vm.provision :shell, path: "vagrant/bootstrap1.sh"
config.vm.provision :shell, path: "vagrant/bootstrap2.sh", run: 'always'
config.vm.provision :shell, path: "vagrant/bootstrap3.sh"

script will be run in order, bootstrap1 then 2 then 3 when the machine is first provisioned

any further time you run vagrant up (or reload) only bootstrap2 will be run


I used ubuntu 18.04. Triggers didnt work for me so i chose to copy post-provision script to vm box and then from a master script execute the desired post-provision:

config.trigger.before :provisioner_run, type: :hook do |t|
    t.info = "Before the provision!"
  end

  config.vm.provision "shell" do |s|
    s.inline = "echo $1  "
    s.args   = [" '--->' Provisioning the environment!"]
  end 
  config.vm.provision "file", source: "scripts/post-provision/.", destination: "/home/vagrant"
  config.vm.provision "shell", path: "scripts/install.sh"
  # config.vm.provision "shell", path: "scripts/bootstrap.sh", run: 'always'

  # config.trigger.after :up do |trigger|
  #   trigger.info = "Installing Monitoring Stack..."
  #   trigger.run_remote = {path: "./install-monitor-stack.sh"}
  # end
end

master script contents uses exec to refresh new shell. You could also use

reset

sudo chmod  +x *.sh
exec /home/vagrant/install-monitor-stack.sh
exec /home/vagrant/bootstrap.sh