Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible pull block device UUID from loop, and use for variable on mount module

Im trying to dynamically pull the UUID for disks that im trying to mount. Role so far:

---
- name: Get UUID of App disks
  shell: blkid {{ UUID_loop }} -s UUID -o value
  loop:
    - /dev/sdh1
    - /dev/sdi1
  loop_control:
    loop_var: UUID_loop
  register: UUID
- set_fact:
    UUID_block: "{{ UUID.results | map(attribute='stdout') | join('\n') }}"
- set_fact:
    UUID_split: "{{ UUID_block.split(' ')[0:] }}"
- name: Mount App Disks
  mount:
    path: "{{ item }}"
    src: UUID={{ UUID_split }}
    fstype: ext4
    state: mounted
  loop:
    - /opt/1
    - /opt/2

The output formats as so:

9c64e0f1-5a87-4b71-b9b1-d2c1ffb99471
386316bb-e503-4f54-b9f7-76a9cc1e5878

I need to know how to have the variable take the output, and split it into unique variables that i can plug into my mount module loop.

The complication seems to root from the fact that there are 2 loops being referenced in the same task. I tried to offload the variability factor to its own task ran previously.

So example, im at the point where I have the UUIDs being populated for each block device, but it formats as a giant string. Example:

UUID=9c64e0f1-5a87-4b71-b9b1-d2c1ffb99471
386316bb-e503-4f54-b9f7-76a9cc1e5878 /opt/1 ext4 defaults 0 0
UUID=9c64e0f1-5a87-4b71-b9b1-d2c1ffb99471
386316bb-e503-4f54-b9f7-76a9cc1e5878 /opt/2 ext4 defaults 0 0

What i need the final product to look like is:

UUID=9c64e0f1-5a87-4b71-b9b1-d2c1ffb99471 /opt/1 ext4 defaults 0 0
UUID=386316bb-e503-4f54-b9f7-76a9cc1e5878 /opt/2 ext4 defaults 0 0

Edit: Thanks for the suggestion so far, here is the debug output for the variable I have created.

- name: Debug UUID Variable
  debug:
    msg:
    - "{{ UUID_block }}"

the output:

TASK [mst : Debug UUID Variable] ****************************************************************************************************************************
ok: [1.2.3.4] =>
  msg:
  - |-
    9c64e0f1-5a87-4b71-b9b1-d2c1ffb99471
    386316bb-e503-4f54-b9f7-76a9cc1e5878
    7a07136d-f08c-4d1e-a4af-345683f15f2b
    5b3599ac-8e80-420c-90e7-900f8b72f0b8
    95216cc8-3db3-4dbb-8e16-500166aafd47
    b7c33504-e8b2-4a23-9bd4-658a5a558733
    06dca596-fc81-4cd3-a6d0-ab1d45010b67

For the external script example, is there any experience had with calling from ansible, transforming the data, and forwarding back into ansible for the modified input?

like image 492
shoughton Avatar asked Oct 29 '25 08:10

shoughton


2 Answers

How about you put your device and mount path in a variable like this:


    devices:
     - device: /dev/sdh1
       mount: /opt/1
     - device: /dev/sdi1
       mount: /opt/2

Then you can do something like this:


    - name: get UUID
      ansible.builtin.command: lsblk {{ item.device }} -no UUID
      loop: "{{ devices }}"
      register: uuid
    
    - name: mount new volumes and create fstab entries
      ansible.posix.mount:
        path: "{{ item.item.mount }}"
        src: UUID={{ item.stdout_lines[0] }}
        state: mounted
        fstype: xfs
        opts: defaults,nofail
      loop: "{{ uuid.results }}"

As the uuid.results variable contains the input variable for each loop. See https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#registering-variables-with-a-loop

like image 57
user2399020 Avatar answered Oct 31 '25 12:10

user2399020


I realize that this question is actually about loops, but I figured people searching up the task you're trying to accomplish might appreciate this answer.

So, while it's possible to use a shell to get the UUID, it can also be obtained more cleanly from Ansible facts:

- name: "refresh facts"
  setup:

- name: "mount new volumes and create fstab entries"
  mount:
    path: "{{ item.mount }}"
    src: "UUID={{ ansible_facts['devices'][item.device | basename]['partitions'][(item.device + '1') | basename]['uuids'] | first }}"
    state: mounted
    fstype: xfs
    opts: defaults,nofail
  loop: "{{ devices }}"

Assuming variables:

devices:
 - device: /dev/sdh
   mount: /opt/1
 - device: /dev/sdi
   mount: /opt/2

Pay attention to the fact that this assumes disks have partitions, but this is not necessarily the case.

like image 23
DustWolf Avatar answered Oct 31 '25 11:10

DustWolf