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

标签 ansible ansible-filter

我有这个剧本:

- 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 的列表在第二个例子中,我得到了一些 AnsibleUndefined输出。
我需要更改什么才能使这些过滤器也适用于单项字典?

最佳答案

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

{
    "key": "bar",
    "value": {
        "type": "v1"
    }
}
解决问题的2个解决方案:
  • 指导 lookup你想要一个列表

  • msg: {{ lookup('dict', foo, wantlist=true) | map(attribute='key') | list }}
    
  • 使用 query代替 lookup它总是返回一个列表,更适合这种处理(循环、映射)

  • msg: {{ query('dict', foo) | map(attribute='key') | list }}
    
    引用:
  • https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#ensuring-list-input-for-loop-using-query-rather-than-lookup
  • 关于Ansible 查找过滤器仅在 hashmap 中有多个项目时才起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67404713/

    相关文章:

    ansible - 如何在 Ansible/Jinja2 中获取变量的插值

    loops - 如果列表为空,Ansible 如何跳过循环

    Ansible:无法重新启动apache2.service:连接超时

    ansible - 如何在 ansible 中循环主机组提供动态值

    Ansible - 如何通过迭代另一个列表来从字典列表中提取特定键[编辑]

    python - ansible过滤器映射数组并放入json模板

    Ansible apt 模块显示 "item changed",但我认为它没有

    windows - 从 Ansible 中注册的变量创建字典/列表

    ansible:将列表中的一个元素过滤为字符串

    ansible - 创建系统接口(interface)名称列表及其 MAC 地址