I am in need to having multiple ansible playbooks per guest. One is doing the regular guest provisioning (so it is part of regular config.vm.provision "ansible" ... entry now), but others are needed to do some tasks later, then box is already provisioned and running (like do some tweaks, backup, updates, reinstalls etc). I do not want to dispose my guest for each of these changes as it takes too much time - tweaks do work just fine.
Perhaps it is trivial to work that around other way, but I am facing some problems manually running these playbooks from host. For now I come with something like this (this is bit broken, do not use by just copy&paste!):
#!/bin/bash
CONFIG_FILE="config.yml"
RUBY=/opt/vagrant/embedded/bin/ruby
JQ=/usr/bin/jq
VB_NAME=`${RUBY} -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load(ARGF))' < "${CONFIG_FILE}" | ${JQ} -r ".config.vb.name"`
PLAYBOOK="ansible/backup.yml"
PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false \
ansible-playbook --connection=ssh --timeout=30 --limit="${VB_NAME}" \
--inventory-file=.vagrant/provisioners/ansible/inventory --extra-vars="@${CONFIG_FILE}" \
${PLAYBOOK}
but this is not really proper approach as it does not work all the times - sometimes it fails due to some env vars required not set.
Anyway, it'd be great if I could have multiple ansible scripts already declared in my Vagrantfile like i.e. config.vm.provision "ansible", name: "backup" ... and then be simply able to tell vagrant to start them for me like with regular vagrant provision backup.
Or from other hand - how can I properly start ansible playbook the way vagrant does?
Search first in Documentation, Issue Tracker, Mailing List, CHANGELOG, Stackoverflow, etc.
Please note that the Vagrant issue tracker is reserved for bug reports and
enhancements. For general usage questions, please use the Vagrant mailing list:
https://groups.google.com/forum/#!forum/vagrant-up. Thank you!
@MarcinOrlowski This feature is already available (since Vagrant 1.1)
⇒ vagrant provision --help
Usage: vagrant provision [vm-name] [--provision-with x,y,z]
--provision-with x,y,z Enable only certain provisioners, by type or by name.
-h, --help Print this help
See https://www.vagrantup.com/docs/provisioning/basic_usage.html#running-provisioners
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-16.04"
config.vm.provision "step1", type: "ansible" do |ansible|
ansible.playbook = "playbook1.yml"
ansible.verbose = true
end
config.vm.provision "step2", type: "ansible" do |ansible|
ansible.playbook = "playbook2.yml"
ansible.verbose = true
end
end
vagrant provision --provision-with step1
For this kind of use case, you also can have a general playbook that includes the _sub-playbooks_ and use Ansible tags to select which task subset(s) you want to apply (keeping only one provisioner definition in your Vagrantfile).
PS @MarcinOrlowski:
how can I properly start ansible playbook the way vagrant does?
With verbose option set, the Ansible provisioners will dump the complete ansible-playbook (and ansible-galaxy) commands in use. You can easily copy-paste them into your shell.
No, this not implemented as I described. Docs say
By default, provisioners are only run once, during the first vagrant up since the last vagrant destroy, unless the --provision flag is set, as noted above.
Optionally, you can configure provisioners to run on every up or reload. They will only be not run if the --no-provision flag is explicitly specified.
So in your example both step1 and step2 would be executed if you do just vagrant up and this is the main reason current implementation is not useful for the scenarios I mentioned as it'd be to easy to accidentaly run too many playbooks (like 99% users would just do vagrant up as most obvious step to have guest up and running). There's simply no way to set it all up that certain provisioner will not be executed unless explicitelly called with --provision-with.
And this is what I am talking about in this feature request. Basicaully it would suffice to have run: "manual" or so added so I'd do
config.vm.box = "bento/ubuntu-16.04"
config.vm.provision "step1", type: "ansible" do |ansible|
ansible.playbook = "playbook1.yml"
ansible.verbose = true
end
config.vm.provision "step2", type: "ansible", run: "manual" do |ansible|
ansible.playbook = "playbook2.yml"
ansible.verbose = true
end
end
and do not need to bother about "step2" provisioner unless I explicitely call vagrant --provision-with step2. Which is what I am missing right now.
With verbose option set, the Ansible provisioners will dump the complete ansible-playbook (and ansible-galaxy) commands in use. You can easily copy-paste them into your shell.
This is what I done already and my bash script is based on that output, yet I seem to miss something as it is not working in 100% as I mentioned. I perhaps overlooked something and I posted that here just in case it'd be much easier for someone to point out what I do miss.
@MarcinOrlowski Thank you for clarifying, as your initial issue description was not obviously requesting to extend the current "multiple provisioner" capabilities of Vagrant.
Your workflow example is quite doable with the run provisioner parameter:
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-16.04"
config.vm.provision "setup", type: "ansible" do |ansible|
ansible.playbook = "setup.yml"
end
config.vm.provision "backup", run: "never", type: "ansible" do |ansible|
ansible.playbook = "backup.yml"
end
end
Which would allow this (vagrant up-friendly) workflow:
# initial VM setup
vagrant up
# Run some other tasks on running VM (e.g. backup in this example)
vagrant provision --provision-with backup
The run: "never" thing is what I was missing. Thanks a lot. I also hope that you see how misleading and incomplete official documentation is.
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
@MarcinOrlowski Thank you for clarifying, as your initial issue description was not obviously requesting to extend the current "multiple provisioner" capabilities of Vagrant.
Your workflow example is quite doable with the run provisioner parameter:
Which would allow this (
vagrant up-friendly) workflow: