Ansible - 使用with_items并在有条件时使用

hfr*_*nco 34 ansible

我有一堆服务器上有四个物理驱动器(/ dev/sda,sdb,sdc和sdd).sda上安装了操作系统.

我需要格式化除sda之外的每个驱动器.我需要检查每个驱动器上是否有数据.如果是的话,我不应该格式化它.

# 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
Run Code Online (Sandbox Code Playgroud)

格式化这些驱动器显然涉及更多步骤,但在创建GPT分区表时,它在上一个任务中失败了.

这是它运行时的样子.您将看到它在上一个任务中失败:

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
Run Code Online (Sandbox Code Playgroud)

知道怎么检查有条件的base_secondary_partition_{{item}}.stat.exists吗?我需要确保如果驱动器上有数据,它将不会格式化它.

udo*_*dan 54

您不需要在item盐中注册结果.当您注册循环的结果(例如with_items)时,注册的值将包含一个键results,该键包含循环的所有结果的列表.(见文档)

您可以循环遍历第一个任务的已注册结果,而不是循环遍历原始设备列表:

- 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:
    - not item | skipped
    - item.stat.exists == false
Run Code Online (Sandbox Code Playgroud)

该条件not item | skipped负责处理未在原始循环(sda)中过滤的元素.

虽然这可能是您问题的解决方案,但您的问题非常有趣.evalJinja2 似乎没有任何功能.虽然您可以连接字符串,但不能将该字符串用作变量名来获取其值...

  • 在Ansible> = v2.2中,您需要使用`with_items:"{{device_stat.results}}"`来实现此目的. (4认同)
  • 你应该使用`{{item.item}}`来完成第二项任务. (2认同)
  • `不是项目 | Skipped` 在更新版本的 ansible 中给出错误。我不知道您是否可以运行不在过滤表达式上的函数,并且只有在实际跳过时才定义跳过。不管怎样,我最终做了“item.skipped is not Defined or item.skipped == false” (2认同)

yae*_*shi 7

您的任务可以如此简单...

- 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
Run Code Online (Sandbox Code Playgroud)