Ansible with_dict 需要一个字典

Ansible with_dict expects a dict

我知道这个问题已经被问过很多次了,但我一定漏掉了什么!

这是重现问题的最小剧本。

这是剧本:

---
- hosts:
    - localhost
  gather_facts: false
  vars:
    zones_hash:
      location1:
        id: 1
        control_prefix: '10.1.254'
        data_prefix: '10.1.100'
      location2:
        id: 2
        control_prefix: '10.2.254'
        data_prefix: '10.2.100'
  tasks:
    - name: "test1"
      debug: var="zones_hash"

    - name: "test2"
      debug: var="item"
      with_dict:
      - "{{ zones_hash }}"

这是输出:

$ ansible --version
ansible 2.3.1.0
  config file = /home/configs/_ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
$ ansible-playbook playbook.yml

PLAY [localhost] *******************************************************************************

TASK [test1] ***********************************************************************************
ok: [localhost] => {
    "zones_hash": {
        "location1": {
            "control_prefix": "10.1.254",
            "data_prefix": "10.1.100",
            "id": 1
        },
        "location2": {
            "control_prefix": "10.2.254",
            "data_prefix": "10.2.100",
            "id": 2
        }
    }
}

TASK [test2] ***********************************************************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "with_dict expects a dict"}

PLAY RECAP *************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1

我希望 task2 中打印的项目变量包含(例如):

key: location1
value: {
  id: 1
  control_prefix: '10.1.254'
  data_prefix: '10.1.100'
}

我们还缺少什么?

看起来 Ansible 的文档需要更新或者您发现了错误。 http://docs.ansible.com/ansible/latest/playbooks_loops.html#looping-over-hashes 使用您的 with_dict 语法,但它似乎不再有效。字典需要与 with_dict.

在同一行
- name: "test2"
  debug: var="item"
  with_dict: "{{ zones_hash }}"
with_dict:
  - "{{ zones_hash }}"

声明了一个 list,其中一个字典作为第一个索引,Ansible 理所当然地抱怨,因为它需要一个字典。

kfreezy 提到的解决方案有效,因为它实际上为 with_dict 提供了字典而不是列表:

with_dict: "{{ zones_hash }}"

这个问题已经有人回答了,但是我用另一种方式解决了我的问题。这可能对其他人有帮助。

字典名称也可能是个问题。我将字典名称命名为 hdfs_dirs,但我看到了 with_dict expects a dict 错误。显然在公共变量中定义了相同的名称,使用相同的名称是不行的。

当我将字典名称更改为 hdfs_paths 时,它起作用了。

还要仔细检查字典的名称。:)

您遇到的问题更多是关于 YAML 语法!

其实,dash/hyphen表示后面是一个列表项。所以当你写- "{{ zones_hash }}"时,你有一个'list of dict'(只有一个项目)而不是'dict' .

要提供你的'dict',这里是你需要写的:

with_dict: 
  "{{ zones_hash }}"

在一行或两行中,重要的是缺少破折号(不像其他答案中所说的那样)。

当您开始使用 Ansible 并且不熟悉 YAML 时,当您需要以 dash/hyphen 开始声明时,并不总是容易理解。您有一些针对该主题的解释 here on Whosebug

另一个帮助您理解和形象化差异的好方法是在 JSON 中转换您的 YAML 代码。这里有一个工具可以做到这一点: