Monday, April 11, 2022

[SOLVED] Ansible Playbook using variable stdout as input to create files

Issue

I'm creating a playbook to verify all NFS present in fstab are mounted and also they are RW [read/write].

Here is the first block of my playbook that is actually working. Compares the mount output with the current fstab.

  tasks:

    -
      name: Get mounted devices
      shell: /usr/bin/mount | /usr/bin/sed -n {'/nfs / {/#/d;p}'} | /bin/awk '{print $3}'
      register: current_mount
    -
      set_fact:
        block_devices: "{{ current_mount.stdout_lines }}"

    -
      shell: /usr/bin/sed -n '/nfs/ {/#/d;p}' /root/testtab | /usr/bin/awk '{print $2}'
      register: fstab
    -
      set_fact:
        fstab_devices: "{{ fstab.stdout_lines }}"
    -
      name: Device not mounted
      fail:
        msg: "ONE OR MORE NFS ARE NOT MOUNTED, PLEASE VERIFY"
      when: block_devices != fstab_devices

Now to verify these are Read/Write ready:

  1. I need to actually create a file inside the paths stored on {{ current_mount }}

1.1) If it succeed we move forward and delete the newly created files

1.2) If there is failure when creating one or all the files, we need to fail the playbook and msg which of them is not read/write [that mean, if we can't touch[create] a file inside then the FS then is not RW ]

I tried to do the below, but it seems that it does not work like that.

    -
      file:
        path: "{{ current_mount }}"/ansibletestfile
        state: touch
    -
      file:
        path: "{{ current_mount }}"/ansibletestfile
        state: absent

This is a sample of whats inside the {{ current_mount }}

/testnfs
/testnfs2
/testnfs3

After doing some research, it seems that to create more than one file within different FS listed in a variable I would have to use the item module, but I had no luck

Please let me know if there is a way to perform this task.


Solution

To achieve:

  1. create a file inside the paths stored on {{ current_mount }}

You need to loop over current_mount.stdout_lines or block_devices, like:

- file:
    path: "{{ item }}/ansibletestfile"
    state: "touch"
  loop: "{{ current_mount.stdout_lines }}"

For 1.1 and 1.2, we can use blocks. So, overall, the code can look like:

- block:
    # Try to touch file
    - file:
        path: "{{ item }}/ansibletestfile"
        state: "touch"
      loop: "{{ current_mount.stdout_lines }}"
  rescue:
    # If file couldn't be touched
    - fail:
        msg: "Could not create/touch file"
  always:
    # Remove the file regardless
    - file:
        path: "{{ item }}/ansibletestfile"
        state: "absent"
      loop: "{{ current_mount.stdout_lines }}"


Answered By - seshadri_c
Answer Checked By - Mildred Charles (WPSolving Admin)