Ansible: send email on unreachable host

Clash Royale CLAN TAG#URR8PPP
I'd like to get an email sent whenever one of the hosts in ansible cannot be reached through SSH.
I've tried to write a playbook to do this (see below). After gathering facts, any unreachable host is discarded, so my task sending the email is never executed for the unreachable hosts.
-name: Check host accessibility
hosts: all
tasks:
- local_action: shell ssh deploy@ansible_hostname echo OK
register: check_ssh
- local_action: debug msg="check_ssh.stdout"
when: check_ssh.stdout != "OK"
Thanks a lot.
ansible
add a comment |
I'd like to get an email sent whenever one of the hosts in ansible cannot be reached through SSH.
I've tried to write a playbook to do this (see below). After gathering facts, any unreachable host is discarded, so my task sending the email is never executed for the unreachable hosts.
-name: Check host accessibility
hosts: all
tasks:
- local_action: shell ssh deploy@ansible_hostname echo OK
register: check_ssh
- local_action: debug msg="check_ssh.stdout"
when: check_ssh.stdout != "OK"
Thanks a lot.
ansible
add a comment |
I'd like to get an email sent whenever one of the hosts in ansible cannot be reached through SSH.
I've tried to write a playbook to do this (see below). After gathering facts, any unreachable host is discarded, so my task sending the email is never executed for the unreachable hosts.
-name: Check host accessibility
hosts: all
tasks:
- local_action: shell ssh deploy@ansible_hostname echo OK
register: check_ssh
- local_action: debug msg="check_ssh.stdout"
when: check_ssh.stdout != "OK"
Thanks a lot.
ansible
I'd like to get an email sent whenever one of the hosts in ansible cannot be reached through SSH.
I've tried to write a playbook to do this (see below). After gathering facts, any unreachable host is discarded, so my task sending the email is never executed for the unreachable hosts.
-name: Check host accessibility
hosts: all
tasks:
- local_action: shell ssh deploy@ansible_hostname echo OK
register: check_ssh
- local_action: debug msg="check_ssh.stdout"
when: check_ssh.stdout != "OK"
Thanks a lot.
ansible
ansible
asked Nov 9 '15 at 16:23
Lluís VilanovaLluís Vilanova
1065
1065
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I've found that using a Python script is the easiest solution (easier than a callback plugin, at least on my ansible version 1.7):
#!/usr/bin/env python
from __future__ import print_function
import ansible.inventory
import ansible.runner
from subprocess import Popen, PIPE
import sys
TO = "root"
def message(subject, body):
p = Popen(["mail", "-s", subject, TO], stdin=PIPE)
p.communicate(input=body)
res = p.wait()
if res != 0:
print("Failed to send message", file=sys.stderr)
def main():
im = ansible.inventory.Inventory()
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=True,
)
run = runner.run()
nosudo = set(run["dark"].keys())
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=False,
inventory=ansible.inventory.Inventory(list(nosudo)),
)
run = runner.run()
nonet = set(run["dark"].keys())
nosudo = nosudo - nonet
for host in nosudo:
message("Host check: %s" % host,
"Cannot execute 'sudo -u root ...' as user 'deploy'.")
for host in nonet:
message("Host check: %s" % host,
"Cannot login into the machine.")
if __name__ == '__main__':
main()
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (ansible.runneris deprecated and no loger available in v2.4)
– Hopobcn
Jan 29 '18 at 14:07
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
add a comment |
Here is my solution for ansible > 2.0 :
- name: Check host accessibility
hosts: all
user: deploy
gather_facts: no
tasks:
- block:
- command: echo OK
- assert:
that:
- ansible_play_hosts == ansible_play_hosts_all
rescue:
- name: send email when something goes wrong (pe, cannot reach a machine)
local_action:
module: mail
host: localhost
to: < email here >
from: < email here >
subject: 'Host check - (ansible_play_hosts_all '
body: 'Cannot login into the machine'
when: inventory_hostname == "< hostname of main server here >"
That's the best solution I've been able to produce so far. It's a pitty that ansible doesn't consider unreachable hosts as to be failed, so a rescue section is never called. I've overcomed that issue counting the number of host that executed the last task vs the total amount of hosts. If it's different it means that at least one host is unreachable, thus executing the assert and going to the rescue section. Then, the second problem is that the assert applies to all hosts, so we have to pick only one host to send the email (in this case I picked the server where ansible is installed).
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f241880%2fansible-send-email-on-unreachable-host%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I've found that using a Python script is the easiest solution (easier than a callback plugin, at least on my ansible version 1.7):
#!/usr/bin/env python
from __future__ import print_function
import ansible.inventory
import ansible.runner
from subprocess import Popen, PIPE
import sys
TO = "root"
def message(subject, body):
p = Popen(["mail", "-s", subject, TO], stdin=PIPE)
p.communicate(input=body)
res = p.wait()
if res != 0:
print("Failed to send message", file=sys.stderr)
def main():
im = ansible.inventory.Inventory()
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=True,
)
run = runner.run()
nosudo = set(run["dark"].keys())
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=False,
inventory=ansible.inventory.Inventory(list(nosudo)),
)
run = runner.run()
nonet = set(run["dark"].keys())
nosudo = nosudo - nonet
for host in nosudo:
message("Host check: %s" % host,
"Cannot execute 'sudo -u root ...' as user 'deploy'.")
for host in nonet:
message("Host check: %s" % host,
"Cannot login into the machine.")
if __name__ == '__main__':
main()
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (ansible.runneris deprecated and no loger available in v2.4)
– Hopobcn
Jan 29 '18 at 14:07
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
add a comment |
I've found that using a Python script is the easiest solution (easier than a callback plugin, at least on my ansible version 1.7):
#!/usr/bin/env python
from __future__ import print_function
import ansible.inventory
import ansible.runner
from subprocess import Popen, PIPE
import sys
TO = "root"
def message(subject, body):
p = Popen(["mail", "-s", subject, TO], stdin=PIPE)
p.communicate(input=body)
res = p.wait()
if res != 0:
print("Failed to send message", file=sys.stderr)
def main():
im = ansible.inventory.Inventory()
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=True,
)
run = runner.run()
nosudo = set(run["dark"].keys())
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=False,
inventory=ansible.inventory.Inventory(list(nosudo)),
)
run = runner.run()
nonet = set(run["dark"].keys())
nosudo = nosudo - nonet
for host in nosudo:
message("Host check: %s" % host,
"Cannot execute 'sudo -u root ...' as user 'deploy'.")
for host in nonet:
message("Host check: %s" % host,
"Cannot login into the machine.")
if __name__ == '__main__':
main()
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (ansible.runneris deprecated and no loger available in v2.4)
– Hopobcn
Jan 29 '18 at 14:07
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
add a comment |
I've found that using a Python script is the easiest solution (easier than a callback plugin, at least on my ansible version 1.7):
#!/usr/bin/env python
from __future__ import print_function
import ansible.inventory
import ansible.runner
from subprocess import Popen, PIPE
import sys
TO = "root"
def message(subject, body):
p = Popen(["mail", "-s", subject, TO], stdin=PIPE)
p.communicate(input=body)
res = p.wait()
if res != 0:
print("Failed to send message", file=sys.stderr)
def main():
im = ansible.inventory.Inventory()
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=True,
)
run = runner.run()
nosudo = set(run["dark"].keys())
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=False,
inventory=ansible.inventory.Inventory(list(nosudo)),
)
run = runner.run()
nonet = set(run["dark"].keys())
nosudo = nosudo - nonet
for host in nosudo:
message("Host check: %s" % host,
"Cannot execute 'sudo -u root ...' as user 'deploy'.")
for host in nonet:
message("Host check: %s" % host,
"Cannot login into the machine.")
if __name__ == '__main__':
main()
I've found that using a Python script is the easiest solution (easier than a callback plugin, at least on my ansible version 1.7):
#!/usr/bin/env python
from __future__ import print_function
import ansible.inventory
import ansible.runner
from subprocess import Popen, PIPE
import sys
TO = "root"
def message(subject, body):
p = Popen(["mail", "-s", subject, TO], stdin=PIPE)
p.communicate(input=body)
res = p.wait()
if res != 0:
print("Failed to send message", file=sys.stderr)
def main():
im = ansible.inventory.Inventory()
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=True,
)
run = runner.run()
nosudo = set(run["dark"].keys())
runner = ansible.runner.Runner(
module_name='command',
module_args='sh -c "echo OK"',
sudo=False,
inventory=ansible.inventory.Inventory(list(nosudo)),
)
run = runner.run()
nonet = set(run["dark"].keys())
nosudo = nosudo - nonet
for host in nosudo:
message("Host check: %s" % host,
"Cannot execute 'sudo -u root ...' as user 'deploy'.")
for host in nonet:
message("Host check: %s" % host,
"Cannot login into the machine.")
if __name__ == '__main__':
main()
answered Nov 9 '15 at 18:08
Lluís VilanovaLluís Vilanova
1065
1065
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (ansible.runneris deprecated and no loger available in v2.4)
– Hopobcn
Jan 29 '18 at 14:07
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
add a comment |
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (ansible.runneris deprecated and no loger available in v2.4)
– Hopobcn
Jan 29 '18 at 14:07
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (
ansible.runner is deprecated and no loger available in v2.4)– Hopobcn
Jan 29 '18 at 14:07
Unfortunately the Python API has changed in ansible >2.0 and this method is no longer valid. (
ansible.runner is deprecated and no loger available in v2.4)– Hopobcn
Jan 29 '18 at 14:07
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
Is there a new alternative?
– Lluís Vilanova
Jan 30 '18 at 16:31
add a comment |
Here is my solution for ansible > 2.0 :
- name: Check host accessibility
hosts: all
user: deploy
gather_facts: no
tasks:
- block:
- command: echo OK
- assert:
that:
- ansible_play_hosts == ansible_play_hosts_all
rescue:
- name: send email when something goes wrong (pe, cannot reach a machine)
local_action:
module: mail
host: localhost
to: < email here >
from: < email here >
subject: 'Host check - (ansible_play_hosts_all '
body: 'Cannot login into the machine'
when: inventory_hostname == "< hostname of main server here >"
That's the best solution I've been able to produce so far. It's a pitty that ansible doesn't consider unreachable hosts as to be failed, so a rescue section is never called. I've overcomed that issue counting the number of host that executed the last task vs the total amount of hosts. If it's different it means that at least one host is unreachable, thus executing the assert and going to the rescue section. Then, the second problem is that the assert applies to all hosts, so we have to pick only one host to send the email (in this case I picked the server where ansible is installed).
add a comment |
Here is my solution for ansible > 2.0 :
- name: Check host accessibility
hosts: all
user: deploy
gather_facts: no
tasks:
- block:
- command: echo OK
- assert:
that:
- ansible_play_hosts == ansible_play_hosts_all
rescue:
- name: send email when something goes wrong (pe, cannot reach a machine)
local_action:
module: mail
host: localhost
to: < email here >
from: < email here >
subject: 'Host check - (ansible_play_hosts_all '
body: 'Cannot login into the machine'
when: inventory_hostname == "< hostname of main server here >"
That's the best solution I've been able to produce so far. It's a pitty that ansible doesn't consider unreachable hosts as to be failed, so a rescue section is never called. I've overcomed that issue counting the number of host that executed the last task vs the total amount of hosts. If it's different it means that at least one host is unreachable, thus executing the assert and going to the rescue section. Then, the second problem is that the assert applies to all hosts, so we have to pick only one host to send the email (in this case I picked the server where ansible is installed).
add a comment |
Here is my solution for ansible > 2.0 :
- name: Check host accessibility
hosts: all
user: deploy
gather_facts: no
tasks:
- block:
- command: echo OK
- assert:
that:
- ansible_play_hosts == ansible_play_hosts_all
rescue:
- name: send email when something goes wrong (pe, cannot reach a machine)
local_action:
module: mail
host: localhost
to: < email here >
from: < email here >
subject: 'Host check - (ansible_play_hosts_all '
body: 'Cannot login into the machine'
when: inventory_hostname == "< hostname of main server here >"
That's the best solution I've been able to produce so far. It's a pitty that ansible doesn't consider unreachable hosts as to be failed, so a rescue section is never called. I've overcomed that issue counting the number of host that executed the last task vs the total amount of hosts. If it's different it means that at least one host is unreachable, thus executing the assert and going to the rescue section. Then, the second problem is that the assert applies to all hosts, so we have to pick only one host to send the email (in this case I picked the server where ansible is installed).
Here is my solution for ansible > 2.0 :
- name: Check host accessibility
hosts: all
user: deploy
gather_facts: no
tasks:
- block:
- command: echo OK
- assert:
that:
- ansible_play_hosts == ansible_play_hosts_all
rescue:
- name: send email when something goes wrong (pe, cannot reach a machine)
local_action:
module: mail
host: localhost
to: < email here >
from: < email here >
subject: 'Host check - (ansible_play_hosts_all '
body: 'Cannot login into the machine'
when: inventory_hostname == "< hostname of main server here >"
That's the best solution I've been able to produce so far. It's a pitty that ansible doesn't consider unreachable hosts as to be failed, so a rescue section is never called. I've overcomed that issue counting the number of host that executed the last task vs the total amount of hosts. If it's different it means that at least one host is unreachable, thus executing the assert and going to the rescue section. Then, the second problem is that the assert applies to all hosts, so we have to pick only one host to send the email (in this case I picked the server where ansible is installed).
answered Jan 30 '18 at 16:49
HopobcnHopobcn
1011
1011
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f241880%2fansible-send-email-on-unreachable-host%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown