# 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](https://fossexperience.hashnode.dev/ansible-hello-world)

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

```yaml
---
- 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…
