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

如何用Ansible按module字段拆分字典列表生成对应目标文件?

问题描述

现有字典列表变量sites:

sites:
  - { site: "https://site1.com", project: "own", module: "2xx" }
  - { site: "https://site2.com", project: "external", module: "2xx" }
  - { site: "https://site3.net", project: "own", module: "ssl" }
  - { site: "https://site4.org", project: "external", module: "ssl2" }
  - { site: "https://site5.co", project: "external", module: "2xx"}

使用模板文件test.yml.j2:

{% for dict_item in sites %}
 - targets:
   - {{ dict_item.site }}
  labels:
   instance: {{ dict_item.site }}
   job: "blackbox_exporter | sites_check"
   project: {{ dict_item.project }}
   module: {{ dict_item.module }}
{% endfor %}

以及Ansible任务:

- name: "Test multi"
  template:
    src: "test.yml.j2"
    dest: "/opt/test/{{ item.module }}.yml"
  with_items: "{{ sites }}"

当前问题:每个生成的{{ module }}.yml文件都包含所有目标的完整列表,内容完全相同。期望每个文件仅包含对应module字段的目标项(比如2xx.yml只保留module为2xx的条目),且不想为每个模块单独写任务,遵循DRY原则。


解决方案

1. 按module分组站点列表

先添加一个set_fact任务,把sites按module字段分组,生成一个键为模块名、值为对应站点列表的字典:

- name: 按module字段分组站点
  set_fact:
    sites_by_module: "{{ sites | groupby('module') | items2dict(key_name='0', value_name='1') }}"

这里用到的Ansible过滤器说明:

  • groupby('module'):将sites列表按module字段分组,输出格式为[('模块名', [对应站点列表]), ...]
  • items2dict:将分组后的列表转换为字典,指定第0位为键、第1位为值。

2. 修改模板与任务

调整模板文件test.yml.j2

将循环对象改为传入的当前模块专属站点列表,不再遍历整个sites:

{% for dict_item in module_sites %}
 - targets:
   - {{ dict_item.site }}
  labels:
   instance: {{ dict_item.site }}
   job: "blackbox_exporter | sites_check"
   project: {{ dict_item.project }}
   module: {{ dict_item.module }}
{% endfor %}

更新Ansible任务

遍历分组后的字典,为每个模块生成对应配置文件,同时传递该模块的站点列表给模板:

- name: 生成各模块的配置文件
  template:
    src: "test.yml.j2"
    dest: "/opt/test/{{ item.key }}.yml"
  vars:
    module_sites: "{{ item.value }}"
  loop: "{{ sites_by_module | dict2items }}"

这样每个模块的配置文件只会包含对应module的目标项,且无需为每个模块单独编写任务,符合DRY原则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:13:29