Demand a Vagrant plugin within the Vagrantfile?

vagrant-reload plugin
vagrant plugins
vagrant ruby
vagrant plugin example
vagrant winrm plugin
vagrant plugin path
vagrant plugin install ignore ssl
vagrant-vbguest

Supposed execution of a Vagrantfile requires a specific Vagrant plugin to be installed. So, basically what you need to do is

$ vagrant plugin install foobar-plugin
$ vagrant up

If you skip the first step, vagrant up fails.

Is there an option in Vagrant to make it install the plugin automatically? In other words: Is it possible to specify within a Vagrantfile which plugins to install automatically before creating and booting up the machine?

2019 Update: Vagrant now has functionality to require plugins through the Vagrantfile via:

Vagrant.configure("2") do |config|
  config.vagrant.plugins = "vagrant-some-plugin"

  # or as array:
  config.vagrant.plugins = ["vagrant-some-plugin", "vagrant-some-other-plugin"]

  # or as hash
  config.vagrant.plugins = {"vagrant-some-plugin" => {"version" => "1.0.0"}}
end

See https://www.vagrantup.com/docs/vagrantfile/vagrant_settings.html

config.vagrant - Vagrantfile, Vagrant will require these plugins be installed and available for the project. If the plugins are not available, it will attempt to automatically install them into the  »Plugin Development Basics Plugins are a great way to augment or change the behavior and functionality of Vagrant. Since plugins introduce additional external dependencies for users, they should be used as a last resort when attempting to do something with Vagrant.

UPDATE Aug 31, 2018: See @Starx's fix below for later versions of Vagrant (1.8 and above)

Here is version based on Louis St. Amour's solution together with Rob Kinyon's comment about re-exec if a new plugin was installeed, I use it successfully in my own setup:

required_plugins = %w(vagrant-share vagrant-vbguest...)

plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
if not plugins_to_install.empty?
  puts "Installing plugins: #{plugins_to_install.join(' ')}"
  if system "vagrant plugin install #{plugins_to_install.join(' ')}"
    exec "vagrant #{ARGV.join(' ')}"
  else
    abort "Installation of one or more plugins has failed. Aborting."
  end
end

Packaging and Distribution - Plugin Development, Prior to reading this, you should be familiar with the plugin development basics. require "rubygems" require "bundler/setup" Bundler::GemHelper.install_tasks. Vagrantfile packaged with the box that is to be used for a given machine. Vagrantfile in your Vagrant home directory (defaults to ~/.vagrant.d). This lets you specify some defaults for your system user. Vagrantfile from the project directory. This is the Vagrantfile that you will be modifying most of the time. Multi-machine overrides if any.

Since I'm a Ruby dev, and Bindler is no longer being maintained, I found it most natural to just write some code at the top of my Vagrantfile to install required plugins if missing (e.g. before Vagrant.configure line)

The following works for me:

required_plugins = %w( vagrant-hostmanager vagrant-someotherplugin )
required_plugins.each do |plugin|
  system "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
end

system, unlike using backticks, will echo the command to stdout, just as running the command yourself would. And this way I don't need yet another strangely named plugin or system to keep track of required plugins which can be updated by Vagrant anyway.

Vagrant Triggers, Triggers can also be defined within the scope of guests in a Vagrantfile. These triggers will only run on the configured guest. An example of a guest only trigger:. Vagrant plugin that configures the virtual machine to use proxies - tmatilai/vagrant-proxyconf

As I pointed out on my answer to your other question, you can use bindler for installing a set of plugins specific to a project using a single command.

If bindler is installed and the required plugin is not, bindler will error out and will abort the process. There is also an open issue related to automatically installing plugins on vagrant ups but so far no one signed up for it yet.

If you don't want to use bindler, you can make use of Vagrant.has_plugin? (available on 1.3.0+) at the top of your Vagrantfile and error out if the required plugin is not installed.

Something like:

unless Vagrant.has_plugin?("vagrant-some-plugin")
  raise 'some-plugin is not installed!'
end

Vagrant.configure("2") do |config|
  config.vm.box = "box-name"
end

UPDATE: Bindler is no longer supported and no equivalent funcionality has been provided by Vagrant core as of May 11th, 2015

Install plugin dependencies from within Vagrantfile · Issue #1874 , Install plugin dependencies from within Vagrantfile #1874 vagrant process might interfere each other due to different plugin requirements. The moment more than one machine is defined within a Vagrantfile, the usage of the various vagrant commands changes slightly. The change should be mostly intuitive. Commands that only make sense to target a single machine, such as vagrant ssh, now require the name of the machine to control.

Please note that as of Vagrant 1.5, you can specify your dependencies in your Gemfile. Per the blog post on the update:

Now, Vagrant 1.5 will automatically load any gems in the "plugins" group in your Gemfile. As an example, here is the Gemfile for a "vagrant-bar" plugin:

source "https://rubygems.org"

group :development do
  gem "vagrant",
    git: "https://github.com/mitchellh/vagrant.git"
end

group :plugins do
  gem "vagrant-foo",
  gem "vagrant-bar", path: "."
end

config.vagrant.plugins does not work inside the Vagrantfile , Successfully merging a pull request may close this issue. None yet. 2 participants​. @briancain · @dimara. For what it's worth, just to note that as of this writing (02/11/2018), and context being running on Windows 10 and plain CMD prompt, the "vagrant box add" command for me required the HTTP_PROXY and HTTPS_PROXY variables to also be set to work correctly.

6 tips to make your life with Vagrant even better!, When my Vagrantfile depends on plugins such as above, it won't work if could require certain files not to be in use or for example the vagrant  The ability to install plugins programmatically would be beneficial in Vagrantfiles. My idea of how this would work is placing plugin dependencies outside of the Vagrant configure blocks like so: plugin 'vagrant-berkshelf', '1.3.2' Vagra

Vagrant Plugin, Is there an option in Vagrant to make it install the plugin automatically? In other words: Is it possible to specify within a Vagrantfile which plugins 

Vagrant: An Overview, Actions are Vagrant actions that allow interaction with Vagrant managed machines. Create a Vagrant Machine. Once the plugin is installed and Vagrantfile 

Comments
  • Definitely the best solution at the moment
  • I've updated the solution on April 20th to use only one "system" call to install all missing plugins.
  • This did not work. It went into an infinite loop of installing the plugins. Somehow the new vagrant process can not pick up the newly installed plugins in the parent vagrant process
  • Thanks for the update. I actually ended up following the solution suggested by mkuzmin here: github.com/mitchellh/vagrant/issues/4347. It involves using a plugin named vagrant plugins and then use some code (very similar to you) in Vagrantfile.
  • @SteveHenty I sympathise with your comment but moving this into a plugin will sort of defeat the purpose of the code (of just being able to git clone...; cd ...; vagrant up first time around).
  • You'll need to 'exec "vagrant #{ARGV.join' '}"' in order to restart the vagrant process with the plugin installed.
  • Good point. In my case I'd hit an error, but see the installing plugin's output and know to re-run the command. Having it re-run automatically would be an even better enhancement. If re-writing it, perhaps I would check to see if any plugin was not installed, and if so, install the plugins first then re-run the script rather than check and install each plugin one at a time...
  • It would be awesome to have Vagrant.has_plugin? command on the shell level or just have vagrant plugin install check if plugin is already there.
  • Well you could always do something like if [ $(vagrant plugin list | egrep 'vagrant-hostsupdater|vagrant-share' -c) == 2 ] ; then echo "All plugins installed." ; else echo "Missing plugin"; fi but there's a reason nobody writes bash scripts if they can help it ;-) Maybe experiment with the vagrant plugin command further?
  • For future Googlers, please note that this answer is a little outdated. You can now specify your dependencies in your Gemfile under a :plugins group that Vagrant will check for. See my answer below for more details.
  • Gemfile is intended for Vagrant plugin development. See github.com/mitchellh/vagrant/issues/8370
  • Isn't that blog post referring to Vagrant plugin development? Vagrant boxes do not generally have Gemfiles, they use Vagrantfiles.
  • You are correct that Vagrant boxes do not have Gemfiles per se (you could have a Vagrantfile that did not require any plugins), but if you are using plugins (the context of the blog was as dependencies for your own plugin, but the same holds true for Vagrantfiles), you should be using a Gemfile to specify those requirements.
  • Thanks, that's helpful. Since many Vagrant users are not ruby devs and will not already have a Gemfile, would you mind explaining how you set that up? I've created one similar to your example, but vagrant up isn't automatically loading anything. Tried bundle install but that's giving a prompt about system Rubygems permissions, which doesn't sound right.