Passing variable to a shell script provisioner in vagrant
Asked Answered
R

7

29

I'm using a simple shell script to provision software for a vagrant setup as seen here.

But can't figure out a way to take the command line arguments passed in to vagrant and send them along to an external shell script. Google reveals that this was added as a feature but I can't find any documentation covering it or examples out there.

Ratha answered 17/3, 2013 at 14:32 Comment(0)
D
35

You're correct. The way to pass arguments is with the :args parameter.

config.vm.provision :shell, :path => "bootstrap.sh", :args => "'first arg' second"

Note that the single quotes around first arg are only needed if you want to include spaces as part of the argument passed. That is, the code above is equivalent to typing the following in the terminal:

$ bootstrap.sh 'first arg' second

Where within the script $1 refers to the string "first arg" and $2 refers to the string "second".

The v2 docs on this can be found here: http://docs.vagrantup.com/v2/provisioning/shell.html

Detrain answered 24/5, 2013 at 20:15 Comment(2)
I don't think this works when the arg is a variable in your vagrantfile. For example:- args: "#{MY_VARIABLE}" and in your .sh script:- echo $1Blanca
Is there a way to pass arguments like vagrant provision --arg1 --arg2? And then accessing those in our provision script. I am almost 99% sure the answer is no but still couldn't stop myself from asking.Dicker
E
12

Indeed, it doesn't work with variables! The correct snytax is :

var1= "192.168.50.4"
var2 = "my_server"
config.vm.provision :shell, :path => 'setup.sh', :args => [var1, var2]

and then, in the shell setup.sh:

echo "### $1 - $2"

> ### 192.168.50.4 - my_server
Essence answered 8/5, 2016 at 20:0 Comment(0)
H
5

Here is alternative way of passing the variables from the environment:

config.vm.provision "shell" do |s|
    s.binary = true # Replace Windows line endings with Unix line endings.
    s.inline = %Q(/usr/bin/env    \
      TRACE=#{ENV['TRACE']}       \
      VERBOSE=#{ENV['VERBOSE']}   \
      FORCE=#{ENV['FORCE']}       \
      bash my_script.sh)
end

Example usage:

TRACE=1 VERBOSE=1 vagrant up
Hydro answered 16/6, 2016 at 0:50 Comment(0)
M
2

For adding explicit arguments, I used this successfully:

config.vm.provision "shell", path: "provision.sh", :args => "--arg1 somearg --arg2 anotherarg"
Metatarsus answered 7/9, 2017 at 10:23 Comment(0)
H
1

Answering my own question based on some info I found in an old version of the docs page:

config.vm.provision :shell, :path => "bootstrap.sh", :args => "'abc'"

-- @user1391445

Hydro answered 17/3, 2013 at 14:32 Comment(0)
B
1

In new versions You can use array:

config.vm.provision :shell, :path => "bootstrap.sh", :args:["first", "second"]

Bovine answered 11/9, 2018 at 9:26 Comment(0)
P
0

For anyone who is looking NOT just for a quick fix but for a clean, sane solution that will withstand the test of time :), here is an architectural perspective:

  1. You can use a library, but that complicates things:
  • when the library changes, you will need to upgrade it and potentially fix the Vagrant file => more work, more headaches
  • when the Vagrant version changes, you might have to update the Vagrant file => more work, more headaches
  1. You can pass the variables and extract their values via EVN['var_name'] as shown in the Tips & Tricks section of the Vagrant docs. But that removes the simplicity from "vagrant up". Now you have to remember what you are passing in every time and you need to type it correctly => more fat-finger errors, more headaches, more time (This comes from the bottom of the page - last tip called Overwrite host locale in SSH session). But at least you don't have to maintain the library along with all other corollary implications. Tips & Tricks, Using ENV

  2. enter image description here Create and manage the variables in the external shell script, or better yet, in a .json blob that the script is consuming - that way you avoid the shrapnel of changes going across your "vagrant up" invocation, your Vagrant file, and finally into your external shell script = > problems will be minor, if any; you know exactly where they will be => easy to configure, easy to fix => little to no headaches, MORE time :)

That said, there might me exceptions to No.3 above where the values truly belong in the Vagrantfile, i.e., settings that pertain to the external configuration of the VM, like host and guest ports, etc. On the other hand, anything that you configure on the VM itself, like new users and their passwords, should happen outside the Vagrantfile as described in No.3 above.

Pneumatics answered 6/10, 2022 at 7:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.