Custom command line args to vagrant-up?

1,334 views
Skip to first unread message

Jim Klo

unread,
Apr 9, 2015, 3:30:23 AM4/9/15
to vagra...@googlegroups.com
Relatively new to Vagrant as well as Ruby.

I've got a multi-box Vagrantfile and wondering if there's a way for me to pass additional command-line arguments to vagrant-up that I can process within the Vagrantfile.

For example, I've got a VM that provisions a server by default against a specific official release of a source repo, however I'd like to have the ability to just pass an argument or flag that can be processed to do some additional provisioning by changing the source repo to different branch. I suppose I could do this using subsequent calls after the vagrant-up with vagrant-ssh, but was hoping to have a handy one-liner.

Thanks,

- Jim

Alvaro Miranda Aguilera

unread,
Apr 9, 2015, 8:44:08 AM4/9/15
to vagra...@googlegroups.com
Hello,

inside the vagrantfile you can use ruby magic like this:

#if not defined, set defaults
ENV['giver']||="12.1.0.2"

That check for the variable giver, if not defined, will setup a defaul

Then later you can call a shell provisioner like this

config.vm.provision :shell, :inline => "bash /vagrant/script.sh #{ENV['giver']}"

Note the #{} expand the variable as ruby see it.

Does this helps?

Alvaro.
> --
> 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.

dragon788

unread,
Apr 9, 2015, 12:10:59 PM4/9/15
to vagra...@googlegroups.com
As Alvaro said, the easiest way is through ENV variable magic. You can prefix your vagrant up with some instance ENV vars and then access those via the ENV call he outlined.

ENV1=prod ENV2=official vagrant up

If you are more comfortable with ruby you could also do some rudimentary argument parsing, but that could easily bump into vagrant's arg parsing, so the other option if ENV isn't your bag, would be having a file with the options you want to use, and then use Ruby to read in the options from the file, this file could be something like dev-env / prod-env and you have a copy with different variables depending on your branch (if you are using the Vagrantfile from a code repo).

Jim Klo

unread,
Apr 9, 2015, 1:57:57 PM4/9/15
to vagra...@googlegroups.com
Yes, that is eventually how I solved this issue.  I actually tried using ARGV, which would have been preferred, but discovered that vagrant’s processing of arguments doesn’t appear to be extensible and barfs at any arguments it does’t know about.  It would be nice if vagrant just ignored anything it didn’t understand, however I can see how that could cause issues downstream, but I can’t imagine ENV vars are much better.  
Maybe if there was a similar syntax as vagrant ssh where anything after the lone ‘--‘   was passed onto the Vagrantfile.  Hint - this would be a nice orthogonal design pattern to have for all commands that interact with the Vagrantfile or another application.

Thanks everyone,

- Jim

Alvaro Miranda Aguilera

unread,
Apr 9, 2015, 7:13:47 PM4/9/15
to vagra...@googlegroups.com
Hello There,

Don't get frustrated and see what vagrant hast to offer.. it does help a lot.

But, if Vagrant is a hammer (or used as a hammer) perhaps is not the
best tool for everything

you may test file/shell/puppet/chef/ansible...

back to your point.. This has been discussed over and over and over,
and you can search those in the groups or github

but basically, your first shot should be always write your own plugin,
or use a separate plugin, check what vagrant triggers has to offer, it
may suit you

ENV is very cool way to have something portable, and look at this in
this way.. you set a variable outside vagrant, and vagrant
transparently pass the argument to a shell script.. magic.. that make
instantly the code to work with

virtualbox
vmware
aws
etc
etc
etc

Alvaro.

Jim Klo

unread,
Apr 10, 2015, 2:56:43 AM4/10/15
to vagra...@googlegroups.com


> On Apr 9, 2015, at 4:13 PM, Alvaro Miranda Aguilera <kik...@gmail.com> wrote:
>
> Hello There,
>
> Don't get frustrated and see what vagrant hast to offer.. it does help a lot.
>
> But, if Vagrant is a hammer (or used as a hammer) perhaps is not the
> best tool for everything
>
> you may test file/shell/puppet/chef/ansible...
>

True, but solving problems by adding complexity rarely works on the long run.

Puppet/chef/ansible are all fine tools, but not ideal for the tiny scale I'm at. That's a lot like using a jet airplane to commute 50 miles.


> back to your point.. This has been discussed over and over and over,
> and you can search those in the groups or github
>

Searching didn't yield many results actually - so it's hard to gauge by the lack of hits that an idea has been discussed to death.

> but basically, your first shot should be always write your own plugin,
> or use a separate plugin, check what vagrant triggers has to offer, it
> may suit you
>

True - but again let's solve a problem by adding complexity? I've never authored a plugin for vagrant so I can't even begin to wonder how much time I'd spend figuring out how to wire up a plugin that just makes extra arguments from the command line accessible from the Vagrantfile.


> ENV is very cool way to have something portable,
> and look at this in
> this way.. you set a variable outside vagrant, and vagrant
> transparently pass the argument to a shell script.. magic..

And just like the NSA, any other process in the same subshell can see the "DickPic" stored in ENV too.

I won't deny that ENV works - but it's not all that's cracked up to be. You've obviously not done much IT administration on secured systems. ENV is good for static state, but will get you into trouble when used as a control feature. For example - bash isn't necessarily your friend with ENV - by default non-interactive shells often will not cascade exported ENV like interactive bash. Hence passing a value via ENV doesn't even work. Use of ENV also violates the idempotent nature of the Vagrantfile file, IMO, setting an ENV for one script, could unintentionally have side effects on another script. It's hard to create side effects like I describe if you could just pass an argument.

Another example that vagrant users might be familiar- SALTSTACK. ENV is static, as I recall, and cannot be modified during execution/parsing of the YAML - all to prevent Environment Variable induced side effects.

I can live with ENV, it solves my immediate problem. I just don't believe it's the optimal solution that should be available, and just kinda sad that there's no simple solution for custom command line args. I'm not complainining, I'm just pointing out that with all the awesomeness that Vagrant is - I'd love to see some feature consistency across commands that behave in similar ways which would make it a better offering for all. IMO, being able to pass arguments to a shell application that executes a script command line is a very common feature. I think 90% of people would expect that kind of behavior I describe by default and wouldn't expect to have to do magic tricks and a lot of work to get that to work.

dragon788

unread,
Apr 10, 2015, 11:09:14 AM4/10/15
to vagra...@googlegroups.com
Ahhh, I get you now. It sounds like you are talking about using Vagrant provision to pass in an external script to configure your VM in a manner that varies from run to run. There is an open issue about "named" provisioners and getting that working. The intended behavior is that you can pass 'vagrant up --provision-with=prod' and then have a couple of shell scripts, one that calls "use-prod.sh" and one that calls "use-dev.sh", and they are "named" prod and dev. Right now the '--provision-with=' functionality works for calling shell or chef or ansible or whatever, but it doesn't work if you have two shell scripts with different names, if you call shell it runs both, period.

Hopefully this is more along the lines of what you are looking for and you can follow that issue on Github.

Jim Klo

unread,
Apr 10, 2015, 12:23:31 PM4/10/15
to vagra...@googlegroups.com
Yes. That's close to my intent. What I wanted was the ability to pass the name and SHA of a Git repo to be fetched by a provisioning script. There's many ways I could do this, but was hoping for command line.  Also I wouldn't expect the provisioning script to be able to read the host ENV.  

I could do this all post provision as well in exactly the way I describe using vagrant ssh -c "/vagrant/do-stuff.sh arg1 arg2". 

I just wanted to use the same convention consistently.  I see now that's not currently possible unless I switch to ENV. 


Thanks,

- JK
--
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/IxxH3f87m9M/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vagrant-up+...@googlegroups.com.

Robert Ford

unread,
Apr 11, 2015, 11:32:26 AM4/11/15
to vagra...@googlegroups.com
I would recommend checking out rove.io and puphpet.com.  Both are online Vagrantfile generators.  Even if you can't use their generated configurations you can look at "design patterns" they both use.  They both gave me great ideas and solutions for learning Vagrant.

For example, one of these will load a .yaml file from Vagrantfile and use that for configuration information.

Thanks,

robo
To unsubscribe from this group and all its topics, send an email to vagrant-up+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages