我定义了一些主机变量:
x_firewall_ports_v4:
- port: '3306'
rules:
- ip: '1.2.3.4/32'
proto: 'tcp'
action: 'ACCEPT'
- ip: '2.3.4.5/32'
proto: 'tcp'
action: 'ACCEPT'
Run Code Online (Sandbox Code Playgroud)
和一个剧本,现在只写出这些项目:
- debug:
msg: "IP: {{ item.1.ip }}"
loop: "{{ x_firewall_ports_v4 | subelements('rules') }}"
when: x_firewall_ports_v4 is defined
Run Code Online (Sandbox Code Playgroud)
这很好用。因为我不想为我的所有服务器设置防火墙规则,所以最后有条件检查。x_firewall_ports_v4但是从主机定义中删除后,我收到此运行时错误:
TASK [firewall : debug] ********************************************************
fatal: [sql]: FAILED! => {"msg": "obj must be a list of dicts or a nested dict"}
Run Code Online (Sandbox Code Playgroud)
我认为问题可能是x_firewall_ports_v4也有子元素。但我是对的,如何测试x_firewall_ports_v4变量是否存在?尝试了带引号、双引号的条件,但显然它不起作用。
该when:子句在每次迭代时进行计算,这意味着该loop:子句在条件之前进行计算。因此,您的问题不是条件,而是尝试在未定义变量上创建子元素查询的循环表达式。
一个简单的解决方法是在循环中为 var 提供一个空列表作为默认值,并忽略缺少的子元素,以便它创建一个空列表:
- debug:
msg: "IP: {{ item.1.ip }}"
loop: "{{ x_firewall_ports_v4 | d([]) | subelements('rules', skip_missing=true) }}"
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要该when:子句,因为空列表将根本不会导致迭代。