6

I am trying to write an Ansible playbook which will identify newly added disks on a RHEL machine. The plan is to run the playbook and cache the disks at that point in time as a fact prior to creating the new disks. After creating the new disks, the the same playbook would be run again and would compute the difference in disks before and after the disks are created.

For example, lsblk initially returns the following:

NAME              SIZE  TYPE
sda               100G  disk
├─sda1              1G  part
└─sda2             99G  part
  ├─rhel-root      50G  lvm
  ├─rhel-swap     7.9G  lvm
  └─rhel-home    41.1G  lvm
sr0              1024M  rom

after adding 8 new disks, lsblk returns:

NAME              SIZE  TYPE
sda               100G  disk
├─sda1              1G  part
└─sda2             99G  part
  ├─rhel-root      50G  lvm
  ├─rhel-swap     7.9G  lvm
  └─rhel-home    41.1G  lvm
sdb              18.6G  disk
sdc              18.6G  disk
sdd              18.6G  disk
sde              18.6G  disk
sdf              18.6G  disk
sdg              18.6G  disk
sdh              18.6G  disk
sdi              18.6G  disk
sr0              1024M  rom

Ideally I would be able to gather an initial list of disks of the form:

['sda']

and after creating the disks gather another list of disks of the form:

['sda', 'sdb', 'sdc', 'sdd', 'sde', 'sdf', 'sdg', 'sdh', 'sdi']

Computing the difference between the two lists would yield:

['sdb', 'sdc', 'sdd', 'sde', 'sdf', 'sdg', 'sdh', 'sdi']

which are the 8 newly created disks.

I am trying to avoid using a shell or command module call if possible.

Nick
  • 1,834
  • 20
  • 32
AC-5
  • 193
  • 1
  • 1
  • 10

3 Answers3

12

This information is automatically gathered via Ansible's fact gathering mechanism. See Variables discovered from systems: Facts.

For example:

#!/usr/bin/env ansible-playbook
- name: Lets look at some disks
  hosts: localhost
  become: false
  gather_facts: true
  tasks:
  - name: Output disk information
    debug:
      var: hostvars[inventory_hostname].ansible_devices

If we instead use the gather_subset configuration on the setup module instead we can speed up the fact gathering and only gather information about system hardware.

We can then combine this with the Python keys() method and the Jinja2 list filter to produce your desired output.

#!/usr/bin/env ansible-playbook
- name: Lets look at some disks
  hosts: localhost
  become: false
  gather_facts: false
  tasks:
  - name: Collect only facts about hardware
    setup:
      gather_subset:
      - hardware

  - name: Output disks
    debug:
      var: hostvars[inventory_hostname].ansible_devices.keys() | list

It is also possible to configure which facts to gather in the Ansible configuration file ansible.cfg using the gather_subset key in the [defaults] section.

If you want to filter out various disk types the easiest way would be to use map('regex_search', '*search string*') to extract the values you want. You can the remove the nulls via select('string').

For example with disks of the form sd*:

#!/usr/bin/env ansible-playbook
- name: Lets look at some disks
  hosts: localhost
  become: false
  gather_facts: false
  tasks:
  - name: Collect only facts about hardware
    setup:
      gather_subset:
      - hardware

  - name: Output disks
    debug:
      var: hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'sd.*') | select('string') | list
U880D
  • 8,601
  • 6
  • 24
  • 40
Nick
  • 1,834
  • 20
  • 32
  • After implementing the solution @Nick suggested, I'm seeing the following output: ` [ "dm-10", "dm-8", "fd0", "sr0", "sda", "sdb", "dm-9", "dm-6", "dm-7", "dm-4", "dm-5", "dm-2", "dm-3", "dm-0", "dm-1" ] ` Running `lsblk` on my machine I do not see any of the device mapper names (dm-#) as listed above and I can correctly see the newly added disks of the form `sdc, sdd, ...`. Am I wrong to expect to be able to see disk names of the form `sdc, sdd...` from `ansible_devices.keys()` – AC-5 Jul 19 '19 at 19:06
  • Are you looking to list just raw disks? just disk partitions? just logical volumes? The information contained in ansible_devices is going to be all of the above and you'll have to filter out what you don't want to see. The lsblk command automatically formats this information visually. dm-X entries are generally device mapper entries for logical volumes. – Nick Jul 19 '19 at 21:45
  • I'm looking just for raw disks. I looked through the entire output from `ansible_devices` and didn't seem to see any of the newly created disk names. I also tried running `lsblk` using `command` in ansible and wasn't able to see the new disks after creation which makes me think the issue may not be with `ansible_disks`. – AC-5 Jul 19 '19 at 21:55
  • The original answer from @Nick works perfectly - I realized I had a stray `connection: local' that I hadn't noticed so I was collecting facts about the wrong machine. – AC-5 Jul 22 '19 at 13:07
  • This info is very valuable. What if want to use on systems that have hd, sd, nvme, xd drives? How do I make this generic to collect these device names? – opti2k4 Aug 27 '20 at 21:43
-2

Try this command after any disk adding you can see the changes:

for d in /sys/class/scsi_device/* ; do echo 1 > $d/device/rescan; done
Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
-2
- name: Check disk size
  debug:
    msg: "{{ ansible_devices[item].size }}"
  loop: "{{ ansible_devices.keys()|list }}"
Sarvatus
  • 7
  • 1