Ansible attach in mail module doesnt work

I have a code as below and i have my html files present in /tmp/sanity/ .
but i am getting error as “Failed to send mail: can’t attach file” i get file not found

  • name: list html files
    run_once: true
    local_action: shell find /tmp/sanity/ -type f -regex “.*.html” | tr -s ‘\n’ ’ ’ | xargs | sort
    register: list_html_files

  • debug: msg=“{{ list_html_files }}”

  • name: generate final email body
    run_once: true
    local_action: shell for i in find /tmp/sanity/ -type f -regex ".*email.*.txt" | sort; do cat $i ;done
    register: email_body

  • debug: msg=“{{email_body}}”

  • name: email results
    become: true
    ignore_errors: true
    run_once: true
    mail:
    host: “{{smtp_host}}”
    port: 25
    body: ‘{{ email_body.stdout }}’
    attach:

  • ‘{{ list_html_files.stdout_lines[0] }}’
    charset: utf8
    delegate_to: localhost

I have a code as below and i have my html files present in /tmp/sanity/ .
but i am getting error as "Failed to send mail: can't attach file" i get file not found

Well that's pretty clear: the file is not found.
Debug what is in list_html_files.stdout_lines[0] and adjust that.
Without any further information it's hard to tell.

On a related note, instead of fragile shell find/tr/xargs/sort , I
would strongly suggest to use the 'find' module.
That will at least return a standard data structure (which is easier
to offer help with).

Dick

Additionally, you can use fileglob - https://docs.ansible.com/ansible/latest/plugins/lookup/fileglob.html for getting desired files from given directory structure.

Hi Dick/Abhijit,

The problem is not searching the file in the location. the problem is “attach” inside mail module doesn’t recognize the variable reference(it takes hard coded path).I dont want to hard code path inside attach. I want to use the variable reference inside attach module.

In the debug of “list_html_files” below it clearly shows that the html files are present. i am using ansible.2.7.5

Pls suggest how can i achieve this.

ok: [10.253.173.111] => {
“msg”: {
“changed”: true,
“cmd”: “find /tmp/sanity_RIC1/ -type f -regex ".*.html" | tr -s ‘\n’ ’ ’ | xargs | sort”,
“delta”: “0:00:00.006235”,
“end”: “2019-09-05 04:03:01.195198”,
“failed”: false,
“rc”: 0,
“start”: “2019-09-05 04:03:01.188963”,
“stderr”: “”,
“stderr_lines”: ,
“stdout”: “/tmp/sanity_RIC1/sanity_RIC1IC01_20190905-040234.html /tmp/sanity_RIC1/sanity_RIC1IC02_20190905-040247.html”,
“stdout_lines”: [
“/tmp/sanity_RIC1/sanity_RIC1IC01_20190905-040234.html /tmp/sanity_RIC1/sanity_RIC1IC02_20190905-040247.html”
]
}

Hi

You deliberately replaced newlines with spaces, so now your creative
find/tr/xargs/sort command yields only one (1) line.
Hence the attach parameter will see one line that isn't a file, and fail.
I will repeat my previous advice: drop the shell and use the find module.
The documentation is here:
https://docs.ansible.com/ansible/latest/modules/find_module.html

That will give you exactly what you want.

Dick

Hi Dick,

Thanks for the Advice. It works like charm.
I modified the code as below and it works as desired. Again Many thanks for your valuable Suggestion

  • name: list html files
    delegate_to: localhost
    find:
    paths: /tmp/sanity
    patterns: ‘*.html’
    run_once: true
    register: list_html_files

  • debug: msg=“{{list_html_files}}”

  • name: email results
    ignore_errors: true
    run_once: true
    mail:
    host: “{{smtp_host}}”
    port: 25
    body: Test
    attach: “{{ item.path }}”
    charset: utf8
    delegate_to: localhost
    with_items: “{{ list_html_files.files }}”