Skip to main content

Command Palette

Search for a command to run...

The proper way of collecting data from multiple servers with Ansible

Updated
2 min read
The proper way of collecting data from multiple servers with Ansible

Ok. Your boos asked your to collect all installed packages on all servers… I already see you running a command on every servers, redirecting output to a temp file, fetching data, merging files… Wake up! It’s only nightmare. You can do it easy way.

For testing purpose - you can use the environment created there: https://fossexperience.hashnode.dev/ansible-hello-world

So - let’s take a look at the code:

---
- hosts: testgroup
  tasks:
    - name: gather
      command: lsusb
      register: result

    - name: make report
      copy:
        dest: report.txt
        content: |
          {% for h in ansible_play_hosts %}
          {% for l in hostvars[h].result.stdout_lines %}
          {{h}};{{l | quote}}
          {% endfor %}
          {% endfor %}
      delegate_to: localhost
      run_once: true

In the '“gather” task we collect whatever we want. In this case - USB devices. And save it in the “result” variable.

The “make report” task is almost ‘normal’ copy. We learn two things:

  • We can use content instead of src. I our case it is a Jinja2 template

  • We can access other hosts variables via hostvars.

Let’s explain the template now.

  • The outer loop. It just loops over all hosts in ansible_play_hosts built-in variable. And assigns it to h.

  • The inner loop. Loops over result.stdout_lines. Which contains the command output nicely split to lines.

We’re delegating the “copy” command to the controller. And we run it only once.

One more thing. Always quote string you’re unsure of. It helps you to avoid real problems. Like crappy CSV with messed fields. Or code injection.

Good luck with with data collection. And wish good luck with data analysis to your boss. She/He’s gonna need it…

More from this blog

F

FOSS Experience

8 posts