首页 > 解决方案 > ansible 将 json 解析为 include_tasks 循环

问题描述

我有以下名为 cust.json 的 json 文件:

{
 "customer":{
        "CUST1":{
                "zone":"ZONE1",
                "site":"ASIA"
        },
       "CUST2":{
                "zone":"ZONE2",
                "site":"EUROPE"
        }
    }
}

我在 main.yml 中使用这个 json 文件来获取客户列表(CUST1 和 CUST2)。

main.yml

- name: Include the vars
  include_vars:
    file: "{{ playbook_dir }}/../default_vars/cust.json"
    name: "cust_json"

- name: Generate customer config 
  include_tasks: create_config.yml
  loop: "{{ cust_json.customer }}"

我希望循环将基本上将每个客户的代码(例如 CUST1)传递给create_config.yml,以便可能发生以下情况:

create_config.yml

- name: Create customer config 
  block:
    - name: create temporary file for customer
      tempfile:
        path: "/tmp"
        state: file
        prefix: "my customerconfig_{{ item }}."
        suffix: ".tgz"
      register: tempfile

    - name: Setup other things
      include_tasks: "othercustconfigs.yml"


这将导致:

  1. 正在生成以下文件:/tmp/mycustomerconfig_CUST1/tmp/mycustomerconfig_CUST2
  2. othercustconfigs.yml为 CUST1 和 CUST2 运行其中的任务。

问题 :

  1. 运行ansible,此时失败:
TASK [myrole : Generate customer config ] ************************************************************************************************************************************************************

fatal: [127.0.0.1]: FAILED! => {
    "msg": "Invalid data passed to 'loop', it requires a list, got this instead: {u'CUST1': {u'site': u'ASIA', u'zone': u'ZONE1'}, u'CUST2': {u'site': u'EUROPE', u'zone': uZONE2'}}. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup."
}

如何循环 JSON 以便正确获取客户列表(CUST1 和 CUST2)?loop: "{{ cust_json.customer }}"显然不起作用。

  1. 如果我设法使上述工作正常进行,是否可以将循环的结果传递给下一个include_tasks: "othercustconfigs.yml?所以基本上,将循环项目从main.yml,然后到config.yml,然后到othercustconfigs.yml。这可能吗?

谢谢!!Ĵ

标签: jsonlinuxansibleansible-2.x

解决方案


cust_json.customer是包含每个客户的一个键的哈希图,而不是列表。

过滤器可以将此哈希图dict2items转换为元素列表,每个元素都包含一个keyvalue属性,例如:

- key: "CUST1"
  value:
    zone: "ZONE1"
    site: "ASIA"
- key: "CUST2"
  value:
    zone: "ZONE2"
    site: "EUROPE"

考虑到这一点,您可以将包含转换为以下内容:

- name: Generate customer config 
  include_tasks: create_config.yml
  loop: "{{ cust_json.customer | dict2items }}"

以及包含文件中的相关任务:

    - name: create temporary file for customer
      tempfile:
        path: "/tmp"
        state: file
        prefix: "my customerconfig_{{ item.key }}."
        suffix: ".tgz"
      register: tempfile

当然,您可以调整所有这些以value在需要时使用元素,例如item.value.site

您可以查看以下文档以获取详细信息和替代解决方案:


推荐阅读