ansible-playbook 実行時のエラーをメールで通知する


mailコールバックプラグイン

mailコールバックプラグインを利用します。 ansible-playbook実行時にエラーがあった場合はメールで通知します。


環境

# cat /etc/redhat-release 
CentOS Linux release 7.3.1611 (Core)

# ansible-playbook --version
ansible-playbook 2.2.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

ansibleEPELのRPMパッケージを利用しています。


コールバックプラグインの準備

今回は以下の理由により、githubから最新のmailコールバックプラグインをダウンロードして利用します。

  • プラグインを直接編集する必要がある
    • メールの宛先や送信元アドレスを指定する場合、設定ファイル等で指定できれば良いのですが、該当のプラグインを確認する限り現時点ではそのような仕組みにはなっていないようです。
  • バグ
    • この記事を作成時点ではRPMパッケージに含まれるmailコールバックプラグインにはバグが存在します。
# mkdir -p ~/ansible/plugins/callback/
# wget -O ~/ansible/plugins/callback/mail_on_failed.py https://raw.githubusercontent.com/ansible/ansible/devel/lib/ansible/plugins/callback/mail.py

mail.pyとは別のファイル名で保存します。同じ名前だと、ansible-playbook実行時にRPMパッケージでインストールされたmail.pyも実行されてしまいます。

コールバックプラグインの編集

v2_runner_on_failed()内のmail()オプションを編集して、宛先を指定します。

~/ansible/plugins/callback/mail_on_failed.py

(snip)
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'notification'
    CALLBACK_NAME = 'mail'
    CALLBACK_NEEDS_WHITELIST = True

    def v2_runner_on_failed(self, res, ignore_errors=False):
(snip)
        mail(sender=sender, subject=subject, body=body, to="foobar@example.com")

    def v2_runner_on_unreachable(self, result):
(snip)

ansible.cfgの編集

保存したプラグインを下記の様に指定します。

callback_plugins=~/ansible/plugins/callback
callback_whitelist=mail_on_failed

playbookの編集

test.yml

存在しない/mail_on_failed_testlsさせてエラーを発生させます。

- hosts: all
  gather_facts: no
  tasks:
    - ping:
    - shell: echo test
    - shell: ls /mail_on_failed_test
    - shell: date

実行と結果

# ansible-playbook -i localhost, -c local test.yml                                                                                                                                                                                                   

PLAY [all] *********************************************************************

TASK [ping] ********************************************************************
ok: [localhost]

TASK [command] *****************************************************************
changed: [localhost]

TASK [command] *****************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "ls /mail_on_failed_test", "delta": "0:00:00.004637", "end": "2017-0X-0X 10:32:28.102568", "failed": true, "rc": 2, "start": "2017-0X-0X 10:32:28.097931", "stderr": "ls: cannot access /mail_on_failed_test: No such file or directory", "stdout": "", "stdout_lines": [], "warnings": []}
        to retry, use: --limit @/root/test.retry

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=1  

メール本文

以下のメールが配送されます。

件名
ls: cannot access /mail_on_failed_test: No such file or directory
本文
The following task failed for host localhost:

command:  {"warn": true, "executable": null, "_uses_shell": true, "_raw_params": "ls /mail_on_failed_test", "removes": null, "creates": null, "chdir": null}

with the following output in standard error:

ls: cannot access /mail_on_failed_test: No such file or directory

A complete dump of the error:

{"changed": true, "cmd": "ls /mail_on_failed_test", "delta": "0:00:00.004637", "end": "2017-0X-0X 10:32:28.102568", "failed": true, "rc": 2, "start": "2017-0X-0X 10:32:28.097931", "stderr": "ls: cannot access /mail_on_failed_test: No such file or directory", "stdout": "", "stdout_lines": [], "warnings": []}