Ansible with_dict期待一个字典

时间:2017-07-28 15:51:53

标签: ansible ansible-2.x

我知道这个问题以前曾被问过多次,但我必须在这里遗漏一些东西!

这是重现问题的最小手册。

这是剧本:

---
- 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中打印的item变量包含(例如):

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

我们缺少什么?

4 个答案:

答案 0 :(得分:3)

看起来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 }}"

答案 1 :(得分:2)

with_dict:
  - "{{ zones_hash }}"

声明一个带有dict作为第一个索引的列表,并且Ansible正确地抱怨,因为它期望一个字典。

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

with_dict: "{{ zones_hash }}"

答案 2 :(得分:1)

您面临的问题更多是关于YAML语法!

实际上,破折号/连字符表示紧随其后的是列表中的一项。因此,当您编写- "{{ zones_hash }}"时,会有一个“ 字典列表”(仅包含一项),而不是“ 字典”。

要提供您的“ dict ”,这是您需要编写的内容:

with_dict: 
  "{{ zones_hash }}"

无论是在一两行中,重要的是连字符的缺失(不像其他答案here中所说的那样)。

当您从Ansible开始并且不熟悉YAML时,何时需要以破折号/连字符开头的声明并不总是很容易理解。您对此主题here on StackOverflow有一些解释。

另一个帮助您理解和可视化差异的好技巧是将您的YAML代码转换为JSON。这是执行此操作的工具:

答案 3 :(得分:0)

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

字典的名称也可能是一个问题。我将字典名称命名为 customer_id p1 p2 1: 1 a b 2: 1 a c 3: 1 b a 4: 1 b c 5: 1 c a 6: 1 c b ,但遇到hdfs_dirs错误。显然,在通用变量中定义了相同的名称,并且不能使用相同的名称。

当我将字典名称更改为with_dict expects a dict时,它起作用了。

再次仔细检查字典的名称。:)