ansiblehostansible-ad-hoc

Can ansible ad-hoc tolerate some hosts failures?


I know ansible playbooks can set max_fail_percentage to allow the playbook to progress if at least that percentage of the hosts succeeded. However, I wanted to run an ad-hoc command that succeded (exit status 0) if at least a percentage of the hosts executed without errors. Is it possible?


Solution

  • If you have a playbook that affects say 10 hosts and at some point during execution it fails on 1 host, Ansible will simply continue (if you don't set max_fail_percentage at all) on all other hosts. This is default behaviour, generally playbooks will stop executing any more steps on a host that has a failure.

    This is mentioned also in Ansible docs: Ansible - max_failure_percentage

    This behaviour is exactly the same for ad hoc commands. Test, test, test...

    EDIT:

    Just Ansible will not do this, however you can override exit status by piping Ansible's output to for example perl one-liner and exit with a different code there, it's quite ugly but works :)

    See example below, it exits with 0 only if > 65% of hosts succeeded, otherwise exit code is 2. In order to catch failures and parse them somehow you need to redirect STDERR to STDOUT from ansible command (thus 2>&1 at the end of the Ansible command, Perl will not see it otherwise)

    $ ansible all -i provisioning/vagrant-inventory -u vagrant --private-key=~/.vagrant.d/insecure_private_key -m ping 2>&1 | perl -pe 'BEGIN { $failed=0; $success=0;} END { $exit_code=( $success/($success+$failed) ) > 0.65 ? 0 : 2; exit $exit_code;} $failed++ if /\| FAILED/i; $success++ if /\| success/i;'
    192.168.111.210 | success >> {
        "changed": false, 
        "ping": "pong"
    }
    
    192.168.111.200 | success >> {
        "changed": false, 
        "ping": "pong"
    }
    
    192.168.111.211 | FAILED => SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh
    
    $ echo $?
    0