Ansible“obj 必须是字典列表或嵌套字典”错误,条件检查不起作用

Dar*_*ick 2 ansible

我定义了一些主机变量:

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变量是否存在?尝试了带引号、双引号的条件,但显然它不起作用。

Zei*_*tor 6

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:子句,因为空列表将根本不会导致迭代。