Ansible 查找过滤器仅在 hashmap 中有多个项目时才起作用

Ansible lookup filter works only if more than one item in hashmap

我有这个剧本:

- name: "This works"
  hosts: localhost
  tasks:
    - debug:
        msg: "{{ lookup('dict', foo) | map(attribute='key') | list}}"
      vars:
        foo:
          bar:
            type: v1
          baz:
            type: v2

- name: "This does not work"
  hosts: localhost
  tasks:
    - debug:
        msg: "{{ lookup('dict', foo) | map(attribute='key') | list}}"
      vars:
        foo:
          bar:
            type: v1

当运行这个时候,我得到以下输出:

PLAY [This works] *******************************************************************************************************************************************************************************************************************************
    
TASK [Gathering Facts] **************************************************************************************************************************************************************************************************************************
ok: [localhost]
   
TASK [debug] ************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "bar",
        "baz"
    ]
}
    
PLAY [This does not work] ***********************************************************************************************************************************************************************************************************************
    
TASK [Gathering Facts] **************************************************************************************************************************************************************************************************************************
ok: [localhost]
    
TASK [debug] ************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "[AnsibleUndefined, AnsibleUndefined]"

你看,它在第一个示例中打印出 barbaz 作为列表,但在第二个示例中我得到了一些 bar 而不是仅包含 bar 的列表=15=]输出。

我需要更改什么才能使这些过滤器也适用于单项字典?

这是因为 lookup 并不总是 return 列表。在你的第二种情况下,如果你调试,你会看到它 return 是一个不在列表中的对象:

{
    "key": "bar",
    "value": {
        "type": "v1"
    }
}

2 种解决问题的方法:

  1. 指示lookup你想要一个列表
msg: {{ lookup('dict', foo, wantlist=true) | map(attribute='key') | list }}
  1. 使用 query 代替 lookup,后者始​​终 return 是一个列表,更适合这种处理(循环、映射)
msg: {{ query('dict', foo) | map(attribute='key') | list }}

参考: