如何在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
原理说明
JMESPath通配符遍历
services.*.containers[*].name是核心的JMESPath表达式:services.*:匹配services下的所有子节点(也就是各个服务名称,比如grafana、prometheus).containers[*]:遍历每个服务下的containers数组中的所有元素.name:提取每个容器对象的name字段
这一步会返回一个二维数组,比如[["docker-compose_grafana_1"], ["docker-compose_prometheus_1"], ...]
Ansible flatten过滤器
用flatten把二维数组转成一维数组,直接得到所有容器名的扁平列表,避免嵌套结构导致的格式问题。如果某个服务没有容器(空数组),flatten会自动忽略空值,保证结果干净。Jinja2循环生成YAML
通过{% for %}循环把一维数组的元素逐个格式化成YAML列表项,得到你需要的格式。
和jq写法的对比
你用jq实现的逻辑大概是jq '.services | to_entries[] | .value.containers[].name',JMESPath的services.*和jq的to_entries[]作用类似,都是遍历所有子节点,只是语法不同——JMESPath用通配符*更简洁,适合在Ansible的过滤器里直接使用。
内容的提问来源于stack exchange,提问作者Mangosniper
相关产品推荐
相关产品推荐

