How add output in a file?

Hi community,
I would like to pull a report which contain hostname and selinux mode (enforcing or permissive). I would like to have just these two output in a txt file. I would also like to have both hostname and sedlinux mode in the same line. With the below playbook I am able to display the results, but don’t know how to put it in a file and how add both variable in a same line. I could use > to direct output in a file but it can add all other facts that I don’t want. How can I achieve this?

---
- name: Get selinux reports
  hosts: all
  tasks:
  - name: hostname and selinux mode
    debug:
            msg:
              - "Hostname: '{{ ansible_hostname }}'"
              - "Selinux mode: '{{ ansible_selinux['mode'] }}'

Thanks!

Hi @techmush!
First of all I hope I got what you are aiming to right, but maybe something like this could help?

---
- name: Get selinux reports
  hosts: all
  tasks:
  - name: hostname and selinux mode
    copy:
      content: "Hostname: '{{ ansible_hostname }}' Selinux mode: '{{ ansible_selinux['mode'] }}'"
      dest: /tmp/info

1 Like

Hi David,
Yes, that’s something I am aiming to achieve. I copied and pasted the playbook and ran it. I will say it ran successfully, since out of 216 servers it just showed failed for five servers. It showed the below error for those servers. I am able to ssh those five servers and I don’t see anything odd.

fatal: [app-server-03]: FAILED! => {“msg”: “The task includes an option with an undefined variable. The error was: ‘dict object’ has no attribute ‘mode’\n\nThe error appears to be in ‘/home/ansible/playbooks/selinux_mode.yml’: line 5, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: hostname and selinux mode\n ^ here\n”}

However for the rest servers I can see there is info file in tmp directory and it has the ansible hostname and selinux mode. I was hoping it’ll has all of the servers. I ssh’ed to some of the server and found out it created info file in every server’s tmp directory except the failed ones.
My goal is just to have one file for all servers. How can get input in a single file instead of having a file for each server?

Thank you for your help.

Try switching from the copy module to lineinfile so the file isn’t clobbered for each host and delegating the task to the localhost?

Thank you Chris, lineinfile worked. I found out that error I mentioned about about five servers is appearing because of selinux status which is disabled in those server. Here is the working playbook.

---
- name: Get selinux reports
  hosts: all
  tasks:
  - name: hostname and selinux mode
    lineinfile:
            path: /tmp/output
            line: "Hostname: '{{ ansible_hostname }}' Selinux mode: '{{ ansible_selinux['mode'] }}'"
            create: yes
    delegate_to: localhost

Now I’m trying to include the selinux status but for some reason it’s still failing and not including those servers. I tried to add ignore_error parameter and it did nothing that might nothing to do with this. I can create another playbook for that or add another task in same playbook, I thought I can check with you guys if there is better way to achieve that. Here is the new playbook I’m trying to make it work.

---
- name: Get selinux reports
  hosts: all
  ignore_errors: yes
  tasks:
  - name: hostname and selinux mode
    lineinfile:
            path: /tmp/outputstatus
            line: "Hostname: '{{ ansible_hostname }}' Selinux mode: '{{ ansible_selinux['mode'] }}' Selinux status: '{{ ansible_selinux['status'] }}"
            create: yes
    delegate_to: localhost

Thanks,

Perhaps try something like this? :man_shrugging:

  - name: hostname and selinux mode
    ansible.builtin.lineinfile:
      path: /tmp/output
      line: "{{ line }}"
      create: true
    vars:
      line: >-
        Hostname: '{{ ansible_hostname }}'
        {% if ansible_selinux['mode'] is defined %}
        Selinux mode: '{{ ansible_selinux['mode'] }}'
        {% else %}
        Selinux mode: false
        {% endif %}
        {% if ansible_selinux['status'] is defined %}
        Selinux status: '{{ ansible_selinux['status'] }}
        {% else %}
        Selinux status: false
        {% endif %}
    delegate_to: localhost
3 Likes

Okay so I misunderstood a bit the final goal. If it is to have one single file with the information of all hosts, then definitely delegating the task to localhost as @chris mentioned will ensure the final file will be present only on the host where the playbook is run

1 Like

It worked, thank you!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.