Как передать результат вывода task со всех хостов в переменную?

Всем привет. У меня есть PLAYBOOK, задача которого, проверять доступные обновления Windows и присылать мне отчет на электронную почту. Все работает прекрасно, но текущая реализация заставляет PLAY отправлять мне письмо о каждом новом хосте из списка. В итоге, если хостов 10, я получу 10 писем. Я хотел бы, чтобы PLAY выполнил сначала первую TASK на всех хостах, записал результат со всех хостов в переменную, а после отправлял бы письмо мне на почту использовав эти данные. Подскажите пожалуйста наиболее правильное решение.

Мой playbook:

---

- name: Create report for Windows updates
  hosts: all
  serial: 1
  tasks:

  - name: Get current date
    ansible.windows.win_powershell:
      script: |
        Get-Date -Format dd.MM.yyyy
    ignore_errors: true
    register: current_date


  - name: Run powershell script to get the number of updates
    ansible.windows.win_powershell:
      script: |
        $server = ([system.net.dns]::GetHostByName("localhost")).hostname 
        $updatesession = [activator]::CreateInstance([type]::GetTypeFromProgID("Microsoft.Update.Session", $Server))
        $updatesearcher = $updatesession.CreateUpdateSearcher()
        $searchresult = $updatesearcher.Search("IsInstalled=0")
        $PatchCount = $searchresult.Updates.Count       
        if($PatchCount -eq 0){echo "$server : $PatchCount updates."}
        elseif($PatchCount -gt 0){echo "$server : $PatchCount updates."}
    ignore_errors: true
    register: updates_result


  - name: Send email
    ansible.windows.win_powershell:
      script: |
        $smtp_server ="myhost"
        $smtp_user = "myuser"
        $smtp_pass = "mypassword"
        $SMTPClient.Port = 465
        $SMTPClient.EnableSsl = "true"
        $SmtpClient.UseDefaultCredentials = "false"
        $email_from = "emailfrom"
        $email_to = "emailto"
        $email_sub = "Windows Updates report"
        $email_body = "
        <hr><h3>Updates result for group {{ server_group }}:</h3>
        <p>Date: {{ current_date.output[0] }}</p><hr>
        <ol><li>{{ updates_result.output[0] }}<//li></ol>
        "
        $SMTPClient = New-Object Net.Mail.SmtpClient($smtp_server)
        $email_msg = New-Object System.Net.Mail.MailMessage
        $email_msg.IsBodyHTML = $true
        $email_msg.From = $email_from
        $email_msg.Subject = $email_sub
        $email_msg.Body = $email_body
        $email_msg.To.Add($email_to)
        $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($smtp_user,$smtp_pass);
        $SMTPClient.Send($email_msg)
    ignore_errors: true


Ответы (1 шт):

Автор решения: Eugene Orlov

Реализовал через вывод результатов для каждого их хостов в файл с последующей отправкой данных из этого файла в тело сообщения через CAT.

- name: Create report for Windows updates
  hosts: all
  serial: 1
  gather_facts: false
  tasks:

  - name: Run powershell script to get the number of updates
    ansible.windows.win_powershell:
      script: |
        $server = ([system.net.dns]::GetHostByName("localhost")).hostname 
        $updatesession = [activator]::CreateInstance([type]::GetTypeFromProgID("Microsoft.Update.Session", $Server))
        $updatesearcher = $updatesession.CreateUpdateSearcher()
        $searchresult = $updatesearcher.Search("IsInstalled=0")
        $PatchCount = $searchresult.Updates.Count       
        if($PatchCount -eq 0){echo "$PatchCount updates."}
        elseif($PatchCount -gt 0){echo "$PatchCount updates."}
    ignore_errors: true
    register: updates_result
    

  - name: Copy powershell script output to file
    copy:
      dest: /tmp/windows_updates_report.txt
      content: |-
          {% for host in ansible_play_hosts_all %}
          <p>{{ host }}: {{  updates_result.output[0] }}</p>
          {% endfor %}
    delegate_to: localhost
    run_once: true
    

  - name: Register var from windows_updates_report file
    shell: "cat /tmp/windows_updates_report.txt"
    delegate_to: localhost
    register: mail_body
→ Ссылка