end_play and end_host are similar, but not exactly the same.
end_play and ansible.builtin.fail are also similar, but not exactly the same.
- end_play will end the play for all hosts and will consider the play "failed"
- ansible.builtin.fail will end the play for certain hosts and will NOT consider the play "failed" (this article)
For example, let's say you have the following playbook which uses ansible.builtin.fail.
---
- hosts: all
tasks:
- ansible.builtin.debug:
msg: Hello World
- name: fail the play for server2
ansible.builtin.fail:
msg: failing the play
when: inventory_hostname == 'server2'
...
And you run this playbook using this command, which runs the playbook against server1, server2 and server3.
ansible-playbook example.yml -i server1,server2,server3
Running this playbook will output the following, where the play was considered failed for only server2.
TASK [ansible.builtin.debug]
ok: [server1] => {
"msg": "Hello World"
}
ok: [server2] => {
"msg": "Hello World"
}
ok: [server3] => {
"msg": "Hello World"
}
TASK [fail the play for server2]
skipping: [server1]
fatal: [server2]: FAILED! => {"changed": false, "msg": "failing the play"}
skipping: [server3]
PLAY RECAP
server1 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
server2 : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
server3 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
On the other hand, let's say you have the following playbook which uses meta: end_host.
---
- hosts: all
tasks:
- ansible.builtin.debug:
msg: Hello World
- name: end the play for server2
meta: end_host
when: inventory_hostname == 'server2'
...
And you run this playbook using this command, which runs the playbook against server1, server2 and server3.
ansible-playbook example.yml -i server1,server2,server3
Running this playbook should return the following, where the play was ended for only server2 but not considered failed.
TASK [ansible.builtin.debug]
ok: [server1] => {
"msg": "Hello World"
}
ok: [server2] => {
"msg": "Hello World"
}
ok: [server3] => {
"msg": "Hello World"
}
TASK [end the play for server2]
skipping: [server1]
ok: [server2]
skipping: [server3]
PLAY RECAP
server1 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
server2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
server3 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
And let's say you have the following playbook which uses meta: end_play.
---
- hosts: all
tasks:
- ansible.builtin.debug:
msg: Hello World
- name: ending the play for all hosts
meta: end_play
...
And you run this playbook using this command, which runs the playbook against server1, server2 and server3.
ansible-playbook example.yml -i server1,server2,server3
Running this playbook will output the following, where the play was ended for all hosts.
TASK [ansible.builtin.debug]
ok: [server1] => {
"msg": "Hello World"
}
ok: [server2] => {
"msg": "Hello World"
}
ok: [server3] => {
"msg": "Hello World"
}
TASK [ending the play for all hosts]
PLAY RECAP
server1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
server2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
server3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Did you find this article helpful?
If so, consider buying me a coffee over at