Search code examples
linuxcsvansiblecentossystemd

Ansible: Playbook to export systemd status into CSV format


We have more than 1000+ VMs running on different Hyper-V nodes. I want to create a report in CSV format for one systemd service status.

For example, I would like to check the running status of postfix whether it's in state started or stopped. These statuses need to be print into CSV file format.

Expected result as below format

enter image description here


Solution

  • Finally, I got solution for this above request. Here is the code below, helpful for others.

    main.yml

    ---
    - name: Generate an HTML report from Jinja2 template
      hosts: postfix-hosts
      gather_facts: true
    
      vars:
    
        #email settings
        email_subject: System status Report
        email_host: stackoverflw.smtp.com
        email_from: noreply@stackoverflw.com
        email_to: AdMin_Stack@stackoverflw.com
    
        #random settings
        csv_path: /tmp
        csv_filename: report.csv
        headers: Hostname,OS,Distro Ver,Kernel Ver,Postfix Status,FQDN,Total VCPU,Total RAM,Total SWAP,Total Disk,Hyper-V
    
      tasks:
    
      - name: Gather last Postfix Status
        ansible.builtin.shell:  systemctl status postfix | egrep -i Active | awk '{ print $2,$3}'
        register: active
    
      - name: Save CSV headers
        ansible.builtin.lineinfile:
          dest: "{{ csv_path }}/{{ csv_filename }}"
          line: "{{ headers }}"
          create: true
          state: present
        delegate_to: localhost
        run_once: true
    
      - name: Build out CSV file
        ansible.builtin.lineinfile:
          dest: "{{ csv_path }}/{{ csv_filename }}"
          line: "{{ inventory_hostname }},{{ ansible_distribution }},{{ ansible_distribution_version }},{{ ansible_kernel }},{{ active.stdout }},{{ ansible_fqdn }},{{ ansible_processor_vcpus }},{{ ansible_memtotal_mb }},{{ ansible_swaptotal_mb }},{{ ansible_devices.vda.partitions.vda1.size }},{{ ansible_product_name }}"
          create: true
          state: present
        delegate_to: localhost
    
      - name: Read in CSV to variable
        community.general.read_csv:
          path: "{{ csv_path }}/{{ csv_filename }}"
        register: csv_file
        delegate_to: localhost
        run_once: true
    
      - name: Send Email
        community.general.mail:
          host: "{{ email_host }}"
          from: "{{ email_from }}"
          port: 25
          to: "{{ email_to }}"
          subject: "[Ansible] {{ email_subject }}"
          body: "{{ lookup('template', 'report.html.j2') }}"
          attach: "{{ csv_path }}/{{ csv_filename }}"
          subtype: html
        delegate_to: localhost
        run_once: true
    

    report.html.j2

    <table style="border: 1px solid black; border-collapse: collapse;">
    <tr>
        {% for header in headers.split(",") %}
        <th style="border: 1px solid black; padding: 8px 16px;">{{ header }}</th>
        {% endfor %}
    </tr>
    {% for host in csv_file.list %}
    <tr>
        {% for header in headers.split(",") %}
        <td style="border: 1px solid black; padding: 8px 16px;">{{ host[header] }}</td>
        {% endfor %}
    </tr>
    {% endfor %}
    </table>
    

    Thanks to the gregsowell blog helped me get these done.