how to determine provider in Vagrantfile

4,509 views
Skip to first unread message

Mark Phillips

unread,
Aug 13, 2013, 9:19:49 AM8/13/13
to vagra...@googlegroups.com
Can someone tell me how to determine vagrant's current provider (i.e. specified with the --provider argument, or the provider of the currently running VM) from within the Vagrantfile?

I want to do this so that I can use a common Vagrantfile for both VirtualBox and AWS, and I'd like to have vagrant conditionally load a file containing my AWS credentials if and only if the provider is aws, and issue an error message if that file is absent, but only if the provider is aws.

I'd like to put something like this near the top of my Vagrantfile:

if <PROVIDER IS AWS>
  if File.exist?("aws.yml")
    aws_config = YAML.load_file('aws.yml')["aws"]
  else                                                                                                        
    puts "Required file aws.yml is missing"                                                                   
    exit                                                                                                      
  end                                                                                                         
end 

It's the <PROVIDER IS AWS> part that I don't know how to do.  Is there a variable that I can check, or a function I can call, that will tell which provider vagrant is using?

Thanks!

rcrcr

unread,
Oct 16, 2013, 12:05:29 PM10/16/13
to vagra...@googlegroups.com
Mark,

Did you ever solve this?

Mark Phillips

unread,
Oct 17, 2013, 7:34:42 AM10/17/13
to vagra...@googlegroups.com

No

--
You received this message because you are subscribed to a topic in the Google Groups "Vagrant" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vagrant-up/XIxGdm78s4I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vagrant-up+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Trevor Roberts

unread,
Oct 17, 2013, 9:11:58 AM10/17/13
to vagra...@googlegroups.com, mphi...@unca.edu
Hello Mark,

Try this...

config.vm.provider :vmware_fusion do |vmware|
<your code specific to this provider>
end

config.vm.provider :virtualbox do |vbox|
<your code specific to this provider>
end

I don't know the provider symbols for AWS or the other provider you are using. So, just substitute as needed. The provider check itself does not need to be in an if statement. Vagrant will only read the code applicable to the provider that it knows it is running.

Let us know if that helps,
Trevor

Rusty Ross

unread,
Oct 17, 2013, 9:22:06 AM10/17/13
to vagra...@googlegroups.com, Trevor Roberts, mphi...@unca.edu
Trevor,

Thank you for this, but it is not what we are asking.

There are valid reasons to access the provider name from within Ruby elsewhere in the Vagrantfile.

By the way, this:

>> The provider check itself does not need to be in an if statement. Vagrant will only read the code applicable to the provider that it knows it is running.

…is actually not correct. If you put this in the Virtualbox block:

abort("This is virtualbox!")

…and do a vagrant up --provider vmware_fusion, Vagrant will still abort with the Virtualbox message.

Best,
Rusty

Mark Phillips

unread,
Oct 17, 2013, 11:19:18 AM10/17/13
to vagrant-up, Trevor Roberts
Trevor, Rusty:

Rusty is absolutely right.  Using the

config.vm.provider ... do |...|
end

construct does NOT result in the code between "do" and "end" only being executed for the specified provider.  It gets executed no matter which provider is specified.  In fact, it often seems to be executed more than once.  For example, if I put the following in my Vagrantfile:

  config.vm.provider :vmware_fusion do |vmware|
    puts "vmware_fusion!!!!"
  end

  config.vm.provider :virtualbox do |vbox|
    puts "virtualbox!!!"
  end

and then type "vagrant up --provider=virtualbox", I see the following output:

vmware_fusion!!!!
virtualbox!!!
vmware_fusion!!!!
virtualbox!!!
vmware_fusion!!!!
virtualbox!!!
Bringing machine 'default' up with 'virtualbox' provider...

It seems to me that what is happening is that Vagrant is processing the entire Vagrantfile in order to build the possible configuration objects.

As Rusty says, though, there are valid reasons to need to access the provider name from within Ruby at various points in the Vagrant file.  In my case, I want to have code in the Vagrant file that loads my AWS credentials from an external file, and which will give an error message if that external file is missing, but only in the case where the requested provider is AWS --- I want Vagrant to ignore the fact that the AWS credentials file is missing if I'm using it to control a Virtualbox instance, for example.

--Mark

Kjetil Midtlie

unread,
Nov 11, 2013, 7:58:36 AM11/11/13
to vagra...@googlegroups.com
I'm sad to say; Vagrant is one BIG spaghetti hack .. and the docs is even worse.

Alas you need to look into the code to find anything useful

I think the STATE is stored in class /lib/vagrant/environment.rb (a MONSTER 800+ loc file)

good luck

regards
K-)

Shawn Neal

unread,
Nov 12, 2013, 11:39:02 AM11/12/13
to vagra...@googlegroups.com
You can put something like this in your Vagrantfile:

  provider = (ARGV[2] || :virtualbox).to_sym
  if provider == :aws
    puts "Loading my secret AWS keys"
  end

While this works, I tend to avoid doing things like this. Instead I put things like this into a config file that is conditionally loaded if they exist or in environment variables.

Andrew Melo

unread,
Nov 12, 2013, 11:52:04 AM11/12/13
to vagra...@googlegroups.com
Hi Shawn,

Do you have an example of such a vagrantfile that looks at a configuration file? My ruby-fu is surprisingly weak.

Cheers,
Anderw


--
You received this message because you are subscribed to the Google Groups "Vagrant" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vagrant-up+...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
--
Andrew Melo

Teemu Matilainen

unread,
Nov 12, 2013, 12:14:14 PM11/12/13
to vagra...@googlegroups.com
On Tue, Nov 12, 2013 at 1:39 PM, Shawn Neal <neal....@gmail.com> wrote:
You can put something like this in your Vagrantfile:

  provider = (ARGV[2] || :virtualbox).to_sym

The default provider can also be set by an environment variable:

provider = (ARGV[2] || ENV['VAGRANT_DEFAULT_PROVIDER'] || :virtualbox).to_sym
 
While this works, I tend to avoid doing things like this. Instead I put things like this into a config file that is conditionally loaded if they exist or in environment variables.

Yeah, that feels really fragile. =)

-- 
Cheers,
  Teemu 

Brian Gonzalez

unread,
May 28, 2014, 12:32:21 PM5/28/14
to vagra...@googlegroups.com

You could also check the provider type from with the provider block, and set up some conditional config there:


  config.vm.provider "digital_ocean" do |provider|

    puts "* Using Digital Ocean Provider *"
    config.ssh.private_key_path = "~/.ssh/id_rsa" if provider.is_a? VagrantPlugins::DigitalOcean::Config

    provider.client_id = DIGITAL_OCEAN_CLIENT_ID
    provider.api_key = DIGITAL_OCEAN_API_KEY
    provider.image = "Ubuntu 13.10 x64"
    provider.region = "San Francisco 1"
  end

Benjamen Keroack

unread,
Jul 21, 2014, 4:09:21 PM7/21/14
to vagra...@googlegroups.com
I just had to implement the hack from earlier in the thread (involving ARGV).

Basically I need to set a variable based on the provider name and use it later on in provision blocks, but there's no way to do this in Vagrant without that type of hack, unfortunately. Global variables
set in provider blocks are not visible outside the block.

Torben Knerr

unread,
Jul 23, 2014, 3:59:53 AM7/23/14
to vagra...@googlegroups.com
Having access to the provider sounds useful, did anyone already create an issue for it?



--
You received this message because you are subscribed to the Google Groups "Vagrant" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vagrant-up+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hamilton Turner

unread,
Aug 22, 2014, 11:50:20 PM8/22/14
to vagra...@googlegroups.com
Main issue I found: https://github.com/mitchellh/vagrant/issues/1867 . Trying to
skim the code + read issues, it seems that the problem is that the chosen provider 
isn't guaranteed to be known yet when the Vagrantfile is being parsed, which means 
that parsing the argument list yourself is likely going to be the main "solution" for some 
time as real support might require a non-trivial rewrite. 

For what it's worth, here's what I'm using. This is literally the first Ruby I've 
ever written, so if someone could improve it to search the entire arg array instead
of assuming provider is the first option given that would be great. 

# Workaround for mitchellh/vagrant#1867
if ARGV[1] and \
   
(ARGV[1].split('=')[0] == "--provider" or ARGV[2])
  provider
= (ARGV[1].split('=')[1] || ARGV[2])
else
  provider
= (ENV['VAGRANT_DEFAULT_PROVIDER'] || :virtualbox).to_sym
end
puts
"Detected #{provider}"

if provider == "aws"
  puts
'If you want to use the AWS provider, you must provide these variables: '
 
<code snip>
end


Thanks,
Hamilton

Hamilton Turner

unread,
Aug 22, 2014, 11:52:56 PM8/22/14
to vagra...@googlegroups.com
Also, that code only works for the "vagrant up" command (e.g. when 
provider is specified). If you need to know the provider for something like "vagrant destroy" 
I'm not sure how you could do that, unless you can have a variable that persists between
vagrantfile loads

Dragos Cirjan

unread,
Nov 23, 2015, 6:08:34 AM11/23/15
to Vagrant
I think you can always use smth like 

VAGRANT_DEFAULT_PROVIDER=lxc vagrant destroy -f

to destroy or do smth else, however I can't pretend I understand why, when using

vagrant up --provider=virtualbox

it works, while when using 

VAGRANT_DEFAULT_PROVIDER=virtualbox vagrant up

it doesn't work. I used your code above.

Dragos Cirjan

unread,
Nov 23, 2015, 6:11:31 AM11/23/15
to Vagrant
Discovered.

You're using: .to_sym function. 

In this case you're code above should transform to:

if provider == :aws
  puts 'If you want to use the AWS provider, you must provide these variables: '
 
<code snip>
end
Reply all
Reply to author
Forward
0 new messages