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

如何在Ansible中提取JSON输出里的Docker Compose容器名称

解决方案:用Ansible json_query批量提取Docker Compose容器名

示例Ansible任务

假设你通过docker_compose模块得到的返回结果(模拟数据)如下:

{
  "services": {
    "grafana": {
      "containers": [{"name": "docker-compose_grafana_1"}]
    },
    "prometheus": {
      "containers": [{"name": "docker-compose_prometheus_1"}]
    },
    "alertmanager": {
      "containers": [{"name": "docker-compose_alertmanager_1"}]
    }
  }
}

可以用以下Ansible任务批量提取所有容器名并生成YAML列表:

- name: 批量提取Docker Compose容器名称
  hosts: your_target_host
  tasks:
    # 假设docker_compose_result是模块返回的变量
    - name: 用json_query提取并格式化容器名
      set_fact:
        container_names: "{{ docker_compose_result | json_query('services.*.containers[*].name') | flatten }}"

    - name: 输出YAML格式的容器列表
      debug:
        msg: |
          container_list:
            {% for name in container_names %}
            - {{ name }}
            {% endfor %}

执行后会得到类似这样的YAML输出:

container_list:
  - docker-compose_grafana_1
  - docker-compose_prometheus_1
  - docker-compose_alertmanager_1

原理说明

  1. JMESPath通配符遍历
    services.*.containers[*].name 是核心的JMESPath表达式:

    • services.*:匹配services下的所有子节点(也就是各个服务名称,比如grafana、prometheus)
    • .containers[*]:遍历每个服务下的containers数组中的所有元素
    • .name:提取每个容器对象的name字段
      这一步会返回一个二维数组,比如[["docker-compose_grafana_1"], ["docker-compose_prometheus_1"], ...]
  2. Ansible flatten过滤器
    用flatten把二维数组转成一维数组,直接得到所有容器名的扁平列表,避免嵌套结构导致的格式问题。如果某个服务没有容器(空数组),flatten会自动忽略空值,保证结果干净。

  3. Jinja2循环生成YAML
    通过{% for %}循环把一维数组的元素逐个格式化成YAML列表项,得到你需要的格式。

和jq写法的对比

你用jq实现的逻辑大概是jq '.services | to_entries[] | .value.containers[].name',JMESPath的services.*和jq的to_entries[]作用类似,都是遍历所有子节点,只是语法不同——JMESPath用通配符*更简洁,适合在Ansible的过滤器里直接使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:50:23