Is there any way to retry playbooks from where they failed?

14,046

I'm not too sure why you'd want to do this as an Ansible playbook should be idempotent and so re-running the whole thing from the start should be completely fine.

That said, if you do have some need for this, Ansible exposes a retry mechanism at the end of a failed playbook that looks like:

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/user/playbook.retry

If you were directly on the box you could then run something along the lines of:

ansible-playbook playbook.yml --limit @/home/user/playbook.retry

To make this be available as a provisioner to Vagrant you need to add another named provisioner so your Vagrantfile might look something like:

Vagrant.configure("2") do |config|
  # ... other configuration

  # Does the normal playbook run
  config.vm.provision "bootstrap", type: "ansible" do |bootstrap|
    bootstrap.playbook = "playbook.yml"
  end

  # Picks up from any failed runs
  # Run this with: "vagrant provision --provision-with resume"
  config.vm.provision "resume", type: "ansible" do |resume|
    resume.playbook = "playbook.yml"
    resume.limit = "--limit @/home/user/playbook.retry"
  end
end

As pointed out in the comments of the Vagrantfile this will then try to run both the playbook.yml playbook and the playbook.retry retry play that is created on a failed run on a first vagrant up. If the playbook.yml fails then it will automatically try and resume (and presumably fail as you are yet to fix why it failed) and then exit.

You could then fix what needed fixing in your playbook or inventory and then run vagrant provision --provision-with resume to run the provisioning block called resume to pick up from where playbook.yml failed when you originally provisioned the instance.

Be warned though that the limit option on playbook will mean that any facts/variables gathered before the previous playbook failed will not be available to the retry attempt. I'm not sure if there's a good way to regather these facts prior to running the retry and as mentioned I'd definitely lean to re-running the whole playbook on failure anyway.

Share:
14,046

Related videos on Youtube

Javier Manzano
Author by

Javier Manzano

JavaScript, Node.js, React, Blockchain, ...

Updated on September 20, 2022

Comments

  • Javier Manzano
    Javier Manzano over 1 year

    Is there any way to retry playbooks from where they failed?

    I'm starting it with

    vagrant provision
    
    • K-Yo
      K-Yo over 6 years
      Can be useful when you have a first task that takes one hour but succeeds and a second one that fails.
  • MrsTang
    MrsTang over 8 years
    with ansible 1.9.2 and vagrant 1.7.4 on macos it doesn't work as listed, replace resume.raw_arguments = "--limit @/home/user/playbook.retry" with resume.limit = "@/home/user/playbook.retry" to get it working. Cause for it is that vagrant provision seems to use 'default' as limit if not configured otherwise.
  • MagicLAMP
    MagicLAMP almost 7 years
    Whenever I put resume of either kind in my Vagrant file, I get " undefined local variable or method `resume'". Using Vagrant 1.9.4 on Ubuntu. I can run the ansible playbook again using "ansible-playbook --private-key=~/.vagrant.d/insecure_private_key -u vagrant -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inve‌​ntory setup.yml" provided I have not provisioned the box with config.ssh.insert_key = false
  • chpatton013
    chpatton013 over 6 years
    "I'm not too sure why you'd want to do this as an Ansible playbook should be idempotent and so re-running the whole thing from the start should be completely fine." Even with a modestly-sized playbook you can wait 15 minutes before getting to the first changed task. Retries are insanely useful with large orchestration efforts.