60

I have a bunch of servers that have four physical drives on them (/dev/sda, sdb, sdc, and sdd). sda has the OS installed on it.

I need to format each drive except sda. I need to check if each drive has data on it. If it does, then I shouldn't format it.

# This will get all physical disks (sda, sdb, sdc, etc) and assign them to disk_var - name: Get disks set_fact: disk_var="{{hostvars[inventory_hostname]["ansible_devices"].keys()|list}}" - name: Check if the disk is partitioned and also ignore sda stat: path=/dev/{{item}}1 with_items: disk_var when: item != 'sda' register: base_secondary_partition_{{item}} - name: Create GPT partition table command: /sbin/parted -s /dev/{{item}} mklabel gpt with_items: disk_var when: item != 'sda' and base_secondary_partition_{{item}}.stat.exists == false 

There's clearly more steps involved into formatting these drives but it fails at the last task when creating the GPT partition table.

Here's what it looks like when it runs. You'll see that it fails at the last task:

TASK: [role | Get disks] ****************************************************** ok: [server1.com] TASK: [role | Check if the disk is partitioned] ******************************* skipping: [server1.com] => (item=sda) ok: [server1.com] => (item=sdd) ok: [server1.com] => (item=sdb) ok: [server1.com] => (item=sdc) TASK: [role | Create GPT partition table] ************************************* fatal: [server1.com] => error while evaluating conditional: base_secondary_partition_sdd.stat.exists == false FATAL: all hosts have already failed -- aborting 

Any idea how I can check the conditional base_secondary_partition_{{item}}.stat.exists? I need to make sure that if there's data on the drive, it will not format it.

2 Answers 2

81

You do not need to register your result with the item salt. When you register the result of a loop (e.g. with_items) the registered value will contain a key results which holds a list of all results of the loop. (See docs)

Instead of looping over your original device list, you can loop over the registered results of the first task then:

- name: Check if the disk is partitioned and also ignore sda stat: path=/dev/{{item}}1 with_items: disk_var when: item != 'sda' register: device_stat - name: Create GPT partition table command: /sbin/parted -s /dev/{{ item.item }} mklabel gpt with_items: "{{ device_stat.results }}" when: - item is not skipped - item.stat.exists == false 

The condition item is not skipped takes care of that elements which have been filtered in the original loop (sda) will not be processed.

While that might be a solution to your problem, your question is very interesting. There seems to be no eval feature in Jinja2. While you can concatenate strings you can not use that string as a variable name to get to its value...

Sign up to request clarification or add additional context in comments.

5 Comments

You should use {{item.item}} for the second task.
Excellent! This should be in ansible examples.
not item | skipped gives errors in more recent versions of ansible. I don't know if you can run functions like not on a filtered expression and skipped is only defined if if it actually skipped. Anyways I ended up doing item.skipped is not defined or item.skipped == false
In Ansible >= v2.2 you need to use with_items: "{{ device_stat.results }}" for this to to work.
not item | skipped gives this warning "[DEPRECATION WARNING]: Using tests as filters is deprecated. Instead of using result|skipped use result is skipped. This feature will be removed in version 2.9. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg." This should be the far more readable item is not skipped
11

Your tasks can be as simple as this...

- stat: path: /dev/{{item}}1 with_items: ansible_devices.keys() when: item != 'sda' register: stats - command: /sbin/parted -s /dev/{{item.item}} mklabel gpt with_items: stats.results when: item.stat | default(false) and item.stat.exists 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.