9

In my Vagrantfile, I have a provisioner like so:

config.vm.provision "reset", type: "shell", run: "always" do |s|
    s.privileged = false
    s.inline = "bash /path/to/my/reset/script.sh"
end

And when normally provisioning vagrant, it runs fine. But what I would like to do, is setup a provisioner that only runs when I manually call it. So if I were to have the following provisioner:

config.vm.provision "otherScript", type: "shell", run: "manual" do |s|
    s.privileged = false
    s.inline = "bash /path/to/my/other/script.sh"
end

I would run it with vagrant provision --provision-with otherScript. I can already do that with other provisioners. But I cannot find a way to make it so when I do things like vagrant provision it skips any with a run setting of manual. I can't find anything in the docs related to it other than that I can use "always".

I have considered using something like fabric or invoke (python 3) but then I would have to set that up on all the computers in my team. Which I can setup with a script, but I figured this may be easier if possible.

Is there a way to accomplish this? To setup a provisioner that only ever runs when I manually call it?

famousgarkin
  • 12,308
  • 5
  • 52
  • 71
skift
  • 979
  • 2
  • 12
  • 25
  • 2
    The shell provisioner looks to only support two modes for run: once (the default) or always, so I think the answer to your posted question is "no, not possible." What is it you are trying to accomplish with this? There might be some alternative solutions to get to the same result. – BrianC Apr 16 '15 at 03:00
  • I agree with @BrianC, if you absolutely need it only run manually then what's wrong with an SSH to the box and then execute the script? – ydaetskcoR Apr 16 '15 at 16:51
  • Yea that is what I was thinking was the case. I just could not find any other documentation on it. I am already writing an ssh script to run my scripts. Thanks. – skift Apr 17 '15 at 17:35

2 Answers2

6

There is a legitimate need for manual/on-demand/explicit provisioners when you need a complex task to be available, repeatable and reproducible across the team, e.g. resetting a database to a clean slate when needed.

Unfortunately, such option is still missing in Vagrant directly. See GitHub for the feature request: https://github.com/mitchellh/vagrant/issues/5355.

Fortunately, it's easy to work around this limitation via the Vagrantfile. It's just Ruby after all.

if ARGV.include? '--provision-with'
  config.vm.provision 'db-reset', type: 'shell', inline: 'mysql ...'
end
famousgarkin
  • 12,308
  • 5
  • 52
  • 71
  • Ooh, I actually like this route. At least, until something comes official or that feature request is implemented. Though I have not been using vagrant as much lately, I use it at work so this would be handy. – skift Jul 11 '16 at 15:49
1

Vagrant now allows you to pass in run: "never" for an option provisioner. You can still run the provisioning manually with vagrant provision --provision-with <name> or by passing in the --provision --provision-with <name> flags.

So for this config, you would run vagrant provision --provision-with otherScript:

config.vm.provision "otherScript", type: "shell", run: "never" do |s|
    s.privileged = false
    s.inline = "bash /path/to/my/other/script.sh"
end

NOTE: You have to manually specify a name for the provisioner, you cannot just rely on the default name given if you don't specify a type. For instance, vagrant provision --provision-with shell will not work with this config:

config.vm.provision "shell", run: "never" do |s|
    s.privileged = false
    s.inline = "bash script.sh"
end
Yep_It's_Me
  • 3,740
  • 4
  • 34
  • 60