I am trying to use ansible hostvars to select a group of disks, here is my code:
- name: Output disk information
debug:
var: hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'nvme.*') | select('string') | list
What I expect is a list of devices beginning with nvme
or an empty list, but I get the var:
value (query if you will) back as well as the list:
ok: [cm42.ag6hq.net] => {
"hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'nvme.*') | select('string') | list": [
"nvme0n1"
]
}
ok: [cm43.ag6hq.net] => {
"hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'nvme.*') | select('string') | list": []
}
What I expected back was:
ok: [cm42.ag6hq.net] => {
[
"nvme0n1"
]
}
ok: [cm43.ag6hq.net] => {
[]
}
So when I use this query within the with_items:
context, it tries to process the whole query, not the resulting list (which is what I expected):
failed: [cm42.ag6hq.net] (item=hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'nvme.*') | select('string') | list) => {"ansible_loop_var": "item", "changed": false, "item": "hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'nvme.*') | select('string') | list", "msg": "Device /dev/hostvars[inventory_hostname].ansible_devices.keys() | map('regex_search', 'nvme.*') | select('string') | list not found."}
Where am I going off the rails here?
Let me see if I can simplify: playbook:
- name: Get list of NVMe block devices
set_fact:
nvme_devices: "{{ hostvars[inventory_hostname]['ansible_devices'] | dict2items | selectattr('key', 'match', '^nvme') | map(attribute='value') | list }}"
- name: Create partitions on the NVMe disks
parted:
device: "/dev/{{ item }}"
number: 1
state: present
align: optimal
unit: "%"
part_type: primary
fs_type: ext4
with_items: "{{ nvme_devices }}"
Output:
TASK [Create partitions on the NVMe disks] *****************************************************************************************************************************
failed: [cm41.ag6hq.net] (item={'virtual': 1, 'links': {'ids': ['nvme-INTEL_SSDPEKNU010TZ_PHKA220103081P0B', 'nvme-eui.0000000001000000e4d25c78cf5e5501'], 'uuids': [], 'labels': [], 'masters': []}, 'vendor': None, 'model': 'INTEL SSDPEKNU010TZ', 'sas_address': None, 'sas_device_handle': None, 'serial': 'PHKA220103081P0B', 'removable': '0', 'support_discard': '512', 'partitions': {}, 'rotational': '0', 'scheduler_mode': 'none', 'sectors': '2000409264', 'sectorsize': '512', 'size': '953.87 GB', 'host': 'Non-Volatile memory controller: Intel Corporation Device f1aa (rev 03)', 'holders': []}) => {"ansible_loop_var": "item", "changed": false, "err": "Error: Could not stat device /dev/{virtual: - No such file or directory.\n", "item": {"holders": [], "host": "Non-Volatile memory controller: Intel Corporation Device f1aa (rev 03)", "links": {"ids": ["nvme-INTEL_SSDPEKNU010TZ_PHKA220103081P0B", "nvme-eui.0000000001000000e4d25c78cf5e5501"], "labels": [], "masters": [], "uuids": []}, "model": "INTEL SSDPEKNU010TZ", "partitions": {}, "removable": "0", "rotational": "0", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "none", "sectors": "2000409264", "sectorsize": "512", "serial": "PHKA220103081P0B", "size": "953.87 GB", "support_discard": "512", "vendor": null, "virtual": 1}, "msg": "Error while getting device information with parted script: '/usr/sbin/parted -s -m /dev/{'virtual': 1, 'links': {'ids': ['nvme-INTEL_SSDPEKNU010TZ_PHKA220103081P0B', 'nvme-eui.0000000001000000e4d25c78cf5e5501'], 'uuids': [], 'labels': [], 'masters': []}, 'vendor': None, 'model': 'INTEL SSDPEKNU010TZ', 'sas_address': None, 'sas_device_handle': None, 'serial': 'PHKA220103081P0B', 'removable': '0', 'support_discard': '512', 'partitions': {}, 'rotational': '0', 'scheduler_mode': 'none', 'sectors': '2000409264', 'sectorsize': '512', 'size': '953.87 GB', 'host': 'Non-Volatile memory controller: Intel Corporation Device f1aa (rev 03)', 'holders': []} -- unit '%' print'", "out": "", "rc": 1}
failed: [cm42.ag6hq.net] (item={'virtual': 1, 'links': {'ids': ['nvme-INTEL_SSDPEKNU010TZ_PHKA219401S71P0B', 'nvme-eui.0000000001000000e4d25cc6ae5c5501'], 'uuids': [], 'labels': [], 'masters': []}, 'vendor': None, 'model': 'INTEL SSDPEKNU010TZ', 'sas_address': None, 'sas_device_handle': None, 'serial': 'PHKA219401S71P0B', 'removable': '0', 'support_discard': '512', 'partitions': {}, 'rotational': '0', 'scheduler_mode': 'none', 'sectors': '2000409264', 'sectorsize': '512', 'size': '953.87 GB', 'host': 'Non-Volatile memory controller: Intel Corporation Device f1aa (rev 03)', 'holders': []}) => {"ansible_loop_var": "item", "changed": false, "err": "Error: Could not stat device /dev/{virtual: - No such file or directory.\n", "item": {"holders": [], "host": "Non-Volatile memory controller: Intel Corporation Device f1aa (rev 03)", "links": {"ids": ["nvme-INTEL_SSDPEKNU010TZ_PHKA219401S71P0B", "nvme-eui.0000000001000000e4d25cc6ae5c5501"], "labels": [], "masters": [], "uuids": []}, "model": "INTEL SSDPEKNU010TZ", "partitions": {}, "removable": "0", "rotational": "0", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "none", "sectors": "2000409264", "sectorsize": "512", "serial": "PHKA219401S71P0B", "size": "953.87 GB", "support_discard": "512", "vendor": null, "virtual": 1}, "msg": "Error while getting device information with parted script: '/usr/sbin/parted -s -m /dev/{'virtual': 1, 'links': {'ids': ['nvme-INTEL_SSDPEKNU010TZ_PHKA219401S71P0B', 'nvme-eui.0000000001000000e4d25cc6ae5c5501'], 'uuids': [], 'labels': [], 'masters': []}, 'vendor': None, 'model': 'INTEL SSDPEKNU010TZ', 'sas_address': None, 'sas_device_handle': None, 'serial': 'PHKA219401S71P0B', 'removable': '0', 'support_discard': '512', 'partitions': {}, 'rotational': '0', 'scheduler_mode': 'none', 'sectors': '2000409264', 'sectorsize': '512', 'size': '953.87 GB', 'host': 'Non-Volatile memory controller: Intel Corporation Device f1aa (rev 03)', 'holders': []} -- unit '%' print'", "out": "", "rc": 1}
It's evident by the "Error: Could not stat device /dev/{virtual: - No such file or directory.\n"
error that nvme_devices
is not a list of device names, but rather apparently the whole device (see item='virtual...
in the output.
So why doesn't "{{ hostvars[inventory_hostname]['ansible_devices'] | dict2items | selectattr('key', 'match', '^nvme') | map(attribute='value') | list }}"
create a list of names?
ANSWER:
because the map attribute is 'value'
and not 'key'
"{{ hostvars[inventory_hostname]['ansible_devices'] | dict2items | selectattr('key', 'match', '^nvme') | map(attribute='key') | list }}"
will create a list of names that begin with nvme.