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?
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