emailansiblenotify

How to remove a temp file after emailing it


I want to remove a temp file after it has been successfully emailed, but leave it in place if the email task fails.

This is my task:

  - name: send email
    mail:
      host: smtp.example.com
      port: 25
      from: "{{ emailme }}"
      to: "{{ emailme }}"
      subject: "initial config script for {{ uppercase_hostname }}"
      body: "Here it is"
      attach: "{{ tempfilename }}"
    notify: remove temp file
    changed_when: true

I had to add the "changed_when" because the mail module returns "ok" when the email is successfully sent, so the handler would not normally be notified. But maybe the email operation will fail - the temp file would still get deleted.

How can I leave the file in place if the email task fails? This could happen if the SMTP server was down or misconfigured, in which case I might need to grab the file by another method. Perhaps there is a way I can treat the "ok" status as if it was "changed"?


Solution

  • You can use a block error handling to leave the file in place if the email task fails. For example:

    - name: Send email and conditionally remove temp file
      block:
    
      - name: Send email 
        mail:
          host: smtp.example.com
          port: 25
          from: "{{ emailme }}"
          to: "{{ emailme }}"  
          subject: "Initial config script for {{ uppercase_hostname }}"
          body: "Here it is"
          attach: "{{ tempfilename }}"
        changed_when: true
    
      - name: Remove temp file
        file:
          path: "{{ tempfilename }}"
          state: absent
    
      rescue:
    
      - name: Debug message that file was left due to failure
        debug:
          msg: "Email failed, leaving {{ tempfilename }} in place."
    

    This will run the email and temp file removal tasks together in a block. If either fails, it will hit the rescue section and skip removing the file, as well as print a debug message that the file was left in place due to the failure.

    The key is using block and rescue to define a group of tasks that succeed or fail together. This way you can take conditional action on failure.