How To Add Debug Messages To Ansible Tower Email Notification?

Hello everyone!

Is it possible to add a debug message to the Tower 3.7.0 email notification? For example, I have a Play that shows a certain package if it was found and then displays the version of said package via the debug message but I would like that information sent in an email notification along with some other Ansible facts such as distro and version.

define a fact using the set_fact module including the information you want to pass, then pass the stdout of that fact to the body of the email message

  • name: “e-mail report”
    mail:

Thank you! I used the “register” module instead but your suggestion worked. The problem now is an email is sent from every host in my Inventory that the Job was executed against. Is there anyway to combine all of the debug messages into one message and place that in the body of my email?

Here is the Playbook I have put together:

`

add run_once = yes and see if that works.

That did it except now I only receive one email with the debug message for first machine the job ran against. Is there a way to get all the machines debug messages into that email body? I’m guessing this is some sort of Jinja for loop to extract the debug msg array?

ok so if you are looking for a single email with data from all the hosts that it is ran against that is a bit more complicated. You need to write the data from each host as a new line to a local file, then include the contents of that file in the email.

so instead of registering your results, create a local file and then add new lines to that file using lineinfile and then output the results in your email…

https://docs.ansible.com/ansible/latest/modules/lineinfile_module.html

In a workflow I use set_stats with aggregate set on to accumulate output from multiple hosts with the playbook/job in serial mode. I then send an email with the data in a separate job/playbook.

Not sure how the output would look if it wasn’t done in serial mode.

Mike

Would you be able to provide these specific task(s) from your Playbook? I keep getting undefined variable errors. Here’s the set_stats and mail portion from my Playbook:

`

  • name: Collect Info About XAGT
    set_stats:
    data:
    xagt_email: “{% if xagt_presence is defined %} XAGT Version ‘{{ ansible_facts.packages[‘xagt’][0][‘version’] }}’ Found on ‘{{ ansible_hostname }}’{% else %} XAGT Not Found on ‘{{ ansible_hostname }}’{% endif %}”
    per_host: no
    aggregate: yes

  • name: XAGT Email Report
    delegate_to: localhost
    mail:

Another alternative is to create a jinja template iterating the host_vars, where all variables are stored, and generate an html table, for example, to be sent in one email by the localhost.

You can use map extract filter against ansible_play_hosts for the debug msg of individual host, which will extract the data from each host and store in to a final result variable via set_fact.

Both this set_fact and email tasks keep it in a block and add run_once to the block.

Based on your code,

  • set_fact:
    Final_output: “{{ ansible_play_hosts | map { ‘extract’, hostvars, ‘xagt_debug[‘msg’]’ | list } }}
    run_once: yes

Thanks and Regards
Mani Mohan

I receive this error when using your suggestion:

`
TASK [set_fact] ****************************************************************
fatal: [my_machines_hostname]: FAILED! => {“msg”: “template error while templating string: expected token ‘end of print statement’, got ‘{’. String: “{{ ansible_play_hosts | map { ‘extract’, hostvars, ‘xagt_debug[‘msg’]’ | list } }}"”}

`

Here are the relevant tasks I have in my Playbook:

`

  • name: Is XAGT Installed?
    debug:
    msg: “{% if xagt_presence is defined %} XAGT Version ‘{{ ansible_facts.packages[‘xagt’][0][‘version’] }}’ Found on ‘{{ ansible_hostname }}’{% else %} XAGT Not Found on ‘{{ ansible_hostname }}’{% endif %}”
    register: xagt_debug

My bad !
For map parenthesis needs to be used not the curly braces. Pls refer below

  • set_fact:
    Final_output: “{{ ansible_play_hosts | map ( ‘extract’, hostvars, ‘xagt_debug[‘msg’]’ | list ) }}
    run_once: yes

Thanks and Regards
Mani Mohan

Still not working:

`

TASK [Set Fact Final output]

93
fatal: [REDACTED]: FAILED! => {“msg”: “template error while templating string: expected token ‘,’, got ‘msg’. String: {{ ansible_play_hosts | map ( ‘extract’, hostvars, ‘xagt_debug[‘msg’]’ | list ) }}”}

`

`

  • name: Set Fact Final output
    set_fact:
    Final_output: “{{ ansible_play_hosts | map ( ‘extract’, hostvars, ‘xagt_debug[‘msg’]’ | list ) }}”
    run_once: yes

`

Looks like, map is having issues reading the data in variable ‘xagt_debug[‘msg’]’
Try setting a teporary fact with data available in the variable ‘xagt_debug[‘msg’]’, and then try the map extract with that variable.

it looks like this

  • name: Is XAGT Installed?
    debug:
    msg: “{% if xagt_presence is defined %} XAGT Version ‘{{ ansible_facts.packages[‘xagt’][0][‘version’] }}’ Found on ‘{{ ansible_hostname }}’{% else %} XAGT Not Found on ‘{{ ansible_hostname }}’{% endif %}”
    register: xagt_debug

  • set_fact:
    temp_var: “{{ xagt_debug[‘msg’] }}”

  • set_fact:
    Final_output: “{{ ansible_play_hosts | map { ‘extract’, hostvars, ‘temp_var’ | list } }}"
    run_once: yes

Thanks and Regards

Mani Mohan

Hello again,

When trying your suggestion, I get this error:

“msg”: “template error while templating string: expected token ‘end of print statement’, got ‘{’. String: {{ ansible_play_hosts | map { ‘extract’, hostvars, ‘temp_var’ | list } }}”

  • name: SET FACT FOR XAGT PACKAGE
    set_fact:
    xagt_presence: “{{ ansible_facts.packages[‘xagt’] }}”
    cacheable: yes
    ignore_errors: True

Looks like we are making progress:

`

  • name: IS XAGT INSTALLED?
    debug:
    msg: “{% if xagt_presence is defined %} XAGT Version ‘{{ ansible_facts.packages[‘xagt’][0][‘version’] }}’ Found on ‘{{ ansible_hostname }}’{% else %} XAGT Not Found on ‘{{ ansible_hostname }}’{% endif %}”
    register: xagt_debug

Yup, something to do with the formatting may be, but yeah most of the times when formatting results from register doesn’t work, fallback option is to set it as a fact in separate task and use the variable, like we do it any other programming languages.

So you are able to see all the accumulated results in Final_output variable ? That debug task also should run once.

Thanks and Regards
Mani Mohan

Doh! Sorry Mani I spoke to soon! I was looking at the wrong “set_fact” in my PLAY RECAP. Even though I was wrong I finally was able to get an output via email of all my hosts using the “Final_output” mapping:

[" XAGT Version '29.7.8' Found on 'hostname redacted'", " XAGT Version '29.7.8' Found on 'hostname redacted'", " XAGT Not Found on 'hostname redacted'", " XAGT Version '29.7.8' Found on 'hostname redacted'", " XAGT Version '29.7.8' Found on 'hostname redacted'", " XAGT Version '29.7.8' Found on 'hostname redacted'", " XAGT Not Found on 'hostname redacted'", " XAGT Version '29.7.8' Found on 'hostname redacted'"]

But I thought the mapping function would provide a list and not everything enclosed in brackets? Would you know how I could get this in a nice list for the email (with maybe one space between each line)?

Here is what worked for the “Final_output” fact

`

  • set_fact:
    temp_var: “{{ xagt_debug[‘msg’] }}”