Ansible:迭代字典中的列表作为条件
Ansible: iterate over a list in dictionary as condition
我创建了一个角色来创建 LVM VG(s) 并使其完全幂等和故障证明我想验证 PV(s) 存在并且 VG 尚未定义。
roles/lvm/vars/main.yml
---
lvm_vgs:
- vg_name: drbdpool
vg_pvs: "{{ vg_drbdpool_pvs }}"
host_vars/hostname
---
vg_drbdpool_pvs: ['sdc1', 'sdd1']
roles/lvm/tasks/main.yml
- name: Create LVM VG(s)
lvg:
vg: "{{ item.vg_name }}"
pvs: "{% for disk in item.vg_pvs %}/dev/{{ disk }}{% if not loop.last %},{% endif %}{% endfor %}"
state: present
when:
- item.vg_name not in ansible_lvm.vgs
- "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}"
with_items: "{{ lvm_vgs }}"
为了实现这一点,我添加了条件 "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}"
,但它不起作用,而且我总是收到以下错误:
TASK [lvm : Create LVM VG(s)] **************************************************
fatal: [hostname]: FAILED! => {"failed": true, "msg": "The conditional check '{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}' failed. The error was: unexpected '.'\n line 1\n\nThe error appears to have been in '/etc/ansible/roles/lvm/tasks/main.yml': line 80, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Create LVM VG(s)\n ^ here\n"}
如何验证 PV(分区)是否存在?
Ansible 假设 when
的参数是一个简单的 Jinja2 表达式(它隐式地添加了 {{
}}
大括号),所以你不能在里面使用语句 {% ... %}
.
解决方法是在任务中定义一个变量,并使用变量名作为条件:
- name: Create LVM VG(s)
lvg:
vg: "{{ item.vg_name }}"
pvs: "{% for disk in item.vg_pvs %}/dev/{{ disk }}{% if not loop.last %},{% endif %}{% endfor %}"
state: present
when:
- item.vg_name not in ansible_lvm.vgs
- partition_exists
with_items: "{{ lvm_vgs }}"
vars:
partition_exists: "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}"
我没法测试你的实际情况,所以我原封不动。
techraf's 把我带到了解决方案。
- name: Create LVM VG(s)
lvg:
vg: "{{ item.vg_name }}"
pvs: "{% for disk in item.vg_pvs %}/dev/{{ disk }}{% if not loop.last %},{% endif %}{% endfor %}"
state: present
when:
- item.vg_name not in ansible_lvm.vgs
- partition_exists.split(';')
with_items: "{{ lvm_vgs }}"
vars:
partition_exists: "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% if not loop.last %};{% endif %}{% endfor %}"
tags: ['storage', 'lvm']
由于item.vg_pvs
可能有多个元素,变量partition_exists
需要创建为列表。
我创建了一个角色来创建 LVM VG(s) 并使其完全幂等和故障证明我想验证 PV(s) 存在并且 VG 尚未定义。
roles/lvm/vars/main.yml
---
lvm_vgs:
- vg_name: drbdpool
vg_pvs: "{{ vg_drbdpool_pvs }}"
host_vars/hostname
---
vg_drbdpool_pvs: ['sdc1', 'sdd1']
roles/lvm/tasks/main.yml
- name: Create LVM VG(s)
lvg:
vg: "{{ item.vg_name }}"
pvs: "{% for disk in item.vg_pvs %}/dev/{{ disk }}{% if not loop.last %},{% endif %}{% endfor %}"
state: present
when:
- item.vg_name not in ansible_lvm.vgs
- "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}"
with_items: "{{ lvm_vgs }}"
为了实现这一点,我添加了条件 "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}"
,但它不起作用,而且我总是收到以下错误:
TASK [lvm : Create LVM VG(s)] **************************************************
fatal: [hostname]: FAILED! => {"failed": true, "msg": "The conditional check '{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}' failed. The error was: unexpected '.'\n line 1\n\nThe error appears to have been in '/etc/ansible/roles/lvm/tasks/main.yml': line 80, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Create LVM VG(s)\n ^ here\n"}
如何验证 PV(分区)是否存在?
Ansible 假设 when
的参数是一个简单的 Jinja2 表达式(它隐式地添加了 {{
}}
大括号),所以你不能在里面使用语句 {% ... %}
.
解决方法是在任务中定义一个变量,并使用变量名作为条件:
- name: Create LVM VG(s)
lvg:
vg: "{{ item.vg_name }}"
pvs: "{% for disk in item.vg_pvs %}/dev/{{ disk }}{% if not loop.last %},{% endif %}{% endfor %}"
state: present
when:
- item.vg_name not in ansible_lvm.vgs
- partition_exists
with_items: "{{ lvm_vgs }}"
vars:
partition_exists: "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% endfor %}"
我没法测试你的实际情况,所以我原封不动。
techraf's
- name: Create LVM VG(s)
lvg:
vg: "{{ item.vg_name }}"
pvs: "{% for disk in item.vg_pvs %}/dev/{{ disk }}{% if not loop.last %},{% endif %}{% endfor %}"
state: present
when:
- item.vg_name not in ansible_lvm.vgs
- partition_exists.split(';')
with_items: "{{ lvm_vgs }}"
vars:
partition_exists: "{% for disk in item.vg_pvs %}ansible_devices[{{ disk | truncate(-1) }}]['partitions']{{ disk }} is defined{% if not loop.last %};{% endif %}{% endfor %}"
tags: ['storage', 'lvm']
由于item.vg_pvs
可能有多个元素,变量partition_exists
需要创建为列表。