You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Ansible中解析JSON响应并为字典动态追加新项

如何在Ansible中将OpenStack Flavor ID关联到对应服务器字典?

原Playbook代码

- name: Create new instances
  hosts: localhost
  gather_facts: false
  vars:

    new_instances:
      test_server1:
        datacenter: "paris"
        type: "A1"

      test_server2:
        datacenter: "london"
        type: "B1"

      test_server3:
        datacenter: "frankfurt"
        type: "C1"

  tasks:
    - name: Retrieve Openstack Flavor info
      openstack.cloud.compute_flavor_info:
        auth:
          auth_url: <secret>
          username: <secret>
          password: <secret>
          project_id: <secret>
        name: "{{ item.value.type }}"
        region_name: "{{ item.value.datacenter }}"
      with_dict: "{{ new_instances }}"
      register: flavor_output

    - debug:
        msg: "{{ flavor_output }}"

执行Playbook后的响应

ok: [localhost] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "flavors": [
                    {
                        "description": null,
                        "disk": 50,
                        "ephemeral": 0,
                        "id": "DptkedSp2f3YhZmLTYLFBf3t",
                        "is_disabled": false,
                        "is_public": true,
                        "name": "A1",
                        "original_name": null,
                        "ram": 7000,
                        "rxtx_factor": 1.0,
                        "swap": "",
                        "vcpus": 2
                    }
                ],
                "item": {
                    "key": "test_server1",
                    "value": {
                        "datacenter": "paris",
                        "type": "A1"
                    }
                }
            },
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "flavors": [
                    {
                        "description": null,
                        "disk": 50,
                        "ephemeral": 0,
                        "id": "W2YcNHm9ZHMfzcP3T3WPjsmm",
                        "is_disabled": false,
                        "is_public": true,
                        "name": "B1",
                        "original_name": null,
                        "ram": 7000,
                        "rxtx_factor": 1.0,
                        "swap": "",
                        "vcpus": 2
                    }
                ],
                "item": {
                    "key": "test_server2",
                    "value": {
                        "datacenter": "london",
                        "type": "B1"
                    }
                }
            },
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "flavors": [
                    {
                        "description": null,
                        "disk": 100,
                        "ephemeral": 0,
                        "id": "drTdyFXRCKsxLy6kjJwKuZmR",
                        "is_disabled": false,
                        "is_public": true,
                        "name": "C1",
                        "original_name": null,
                        "ram": 15000,
                        "rxtx_factor": 1.0,
                        "swap": "",
                        "vcpus": 4
                    }
                ],
                "item": {
                    "key": "test_server3",
                    "value": {
                        "datacenter": "frankfurt",
                        "type": "C1"
                    }
                }
            }
        ],
        "skipped": false
    }
}

当前尝试的方法及问题

使用json_query提取Flavor ID:

- debug:
    msg: "{{ flavor_output | json_query('results[*].flavors[*].id') }}"

返回结果仅包含ID列表,无法关联到具体服务器:

ok: [localhost] => {
    "msg": [
        [
            "DptkedSp2f3YhZmLTYLFBf3t"
        ],
        [
            "W2YcNHm9ZHMfzcP3T3WPjsmm"
        ],
        [
            "drTdyFXRCKsxLy6kjJwKuZmR"
        ]
    ]
}

最终目标

将每台服务器对应的Flavor ID追加到new_instances字典中,最终格式如下:

new_instances:
  test_server1:
    datacenter: "paris"
    type: "A1"
    flavor_id: "DptkedSp2f3YhZmLTYLFBf3t"

  test_server2:
    datacenter: "london"
    type: "B1"
    flavor_id: "W2YcNHm9ZHMfzcP3T3WPjsmm"

  test_server3:
    datacenter: "frankfurt"
    type: "C1"
    flavor_id: "drTdyFXRCKsxLy6kjJwKuZmR"

解决方案

通过set_fact结合循环和字典合并实现需求:

1. 提取服务器与Flavor ID的映射关系

- name: Extract flavor IDs with server names
  set_fact:
    flavor_id_map: >-
      {{
        flavor_id_map | default({}) |
        combine({ item.item.key: item.flavors.0.id })
      }}
  loop: "{{ flavor_output.results }}"

2. 将Flavor ID追加到原服务器字典

- name: Update new_instances with flavor IDs
  set_fact:
    new_instances: >-
      {{
        new_instances |
        combine({
          item.key: item.value | combine({ 'flavor_id': flavor_id_map[item.key] })
        })
      }}
  loop: "{{ new_instances | dict2items }}"

3. 验证最终结果

- name: Show updated new_instances
  debug:
    var: new_instances

完整Playbook示例

- name: Create new instances
  hosts: localhost
  gather_facts: false
  vars:
    new_instances:
      test_server1:
        datacenter: "paris"
        type: "A1"
      test_server2:
        datacenter: "london"
        type: "B1"
      test_server3:
        datacenter: "frankfurt"
        type: "C1"

  tasks:
    - name: Retrieve Openstack Flavor info
      openstack.cloud.compute_flavor_info:
        auth:
          auth_url: <secret>
          username: <secret>
          password: <secret>
          project_id: <secret>
        name: "{{ item.value.type }}"
        region_name: "{{ item.value.datacenter }}"
      with_dict: "{{ new_instances }}"
      register: flavor_output

    - name: Extract flavor IDs with server names
      set_fact:
        flavor_id_map: >-
          {{
            flavor_id_map | default({}) |
            combine({ item.item.key: item.flavors.0.id })
          }}
      loop: "{{ flavor_output.results }}"

    - name: Update new_instances with flavor IDs
      set_fact:
        new_instances: >-
          {{
            new_instances |
            combine({
              item.key: item.value | combine({ 'flavor_id': flavor_id_map[item.key] })
            })
          }}
      loop: "{{ new_instances | dict2items }}"

    - name: Show updated new_instances
      debug:
        var: new_instances

说明

  • flavor_id_map:循环flavor_output.results,将服务器名称与对应Flavor ID组合成映射字典,其中item.flavors.0.id是因为返回的flavors是单元素列表,直接取第一个元素的ID。
  • 字典合并:使用dict2items将原new_instances转为列表格式,循环每个服务器条目,通过combine将flavor_id键值对追加到对应服务器的子字典中,再合并回原字典结构。

内容的提问来源于stack exchange,提问作者Tony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:57:55