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

借助Ansible从Inventory API返回内容解析扁平化清单

解析Inventory API数据生成环境分组清单的方案

需求说明

需要解析API返回的CSV格式字符串,生成按环境分组、包含唯一服务器名的Ansible Inventory清单。原始API返回数据如下:

""Name","Status","Environnement",
"srvin-host1","Active","PRODUCTION",
"srvin-host1","Active","PRODUCTION",
"srvin-host1","Active","PRODUCTION",
"srvin-host10","Active","PRODUCTION",
"srvin-host2","Active","PRODUCTION",
"srvin-host2","Active","PRODUCTION",
"srvin-host3","Active","PRODUCTION""

以下提供两种实现方案:Ansible原生任务方案(无需额外Python脚本)、入门级Python脚本方案(适合刚接触Python的场景)。


方案一:Ansible原生任务实现

步骤1:清理原始API返回字符串

先将带格式的原始字符串转换为标准CSV格式:

- name: 清理API返回的原始字符串
  set_fact:
    cleaned_csv: "{{ api_raw_data | regex_replace('^\"|\"$', '') | regex_replace('<br />', '\n') }}"

说明:api_raw_data替换为存储API返回结果的变量名,此步骤去掉首尾冗余引号,将<br />替换为换行符,得到标准CSV文本。

步骤2:解析CSV并去重

将CSV文本转换为结构化列表,并去除重复的主机条目:

- name: 解析CSV并去重
  set_fact:
    inventory_list: "{{ cleaned_csv | split('\n') | map('trim') | reject('equalto', '') | map('split', ',') | map('map', 'regex_replace', '^\"|\"$', '') | list | unique }}"

说明:依次完成行分割、去除空行、字段分割、去除字段引号、去重操作,最终得到包含表头和唯一主机条目的列表。

步骤3:按环境分组构建Inventory结构

循环处理主机条目,按环境名称分组:

- name: 按环境分组构建Inventory字典
  set_fact:
    grouped_inventory: "{{ grouped_inventory | default({}) | combine({ item[2]: (grouped_inventory[item[2]] | default([])) + [item[0]] }) }}"
  loop: "{{ inventory_list[1:] }}"  # 跳过第一行表头

说明:遍历所有主机条目(跳过表头),将每个主机名添加到对应环境的列表中,最终得到{ "PRODUCTION": ["srvin-host1", "srvin-host10", ...] }的结构。

步骤4:生成Inventory文件

将分组后的结构写入静态Inventory文件:

- name: 生成Inventory文件
  copy:
    content: |
      {% for env, hosts in grouped_inventory.items() %}
      [{{ env }}]
      {% for host in hosts %}
      {{ host }}
      {% endfor %}
      {% endfor %}
    dest: ./inventory.ini

执行完后,会在当前目录生成inventory.ini,内容如下:

[PRODUCTION]
srvin-host1
srvin-host10
srvin-host2
srvin-host3

方案二:入门级Python脚本实现

如果更倾向用Python处理,以下是简洁易懂的脚本(适合刚接触Python的用户):

# 替换为API返回的原始字符串
raw_api_data = '''""Name","Status","Environnement",
"srvin-host1","Active","PRODUCTION",
"srvin-host1","Active","PRODUCTION",
"srvin-host1","Active","PRODUCTION",
"srvin-host10","Active","PRODUCTION",
"srvin-host2","Active","PRODUCTION",
"srvin-host2","Active","PRODUCTION",
"srvin-host3","Active","PRODUCTION""'''

# 1. 清理数据:去掉首尾引号,替换换行标签,分割成每行
cleaned_lines = raw_api_data.strip('"').replace('<br />', '\n').split('\n')

# 2. 按环境分组并去重
inventory_groups = {}
for line in cleaned_lines:
    line = line.strip().rstrip(',')  # 去掉行尾逗号和空白
    if not line:
        continue
    # 拆分字段并去掉引号
    parts = [field.strip('"') for field in line.split(',')]
    if parts[0] == 'Name':  # 跳过表头行
        continue
    host_name = parts[0]
    env_name = parts[2]
    # 用集合自动去重
    if env_name not in inventory_groups:
        inventory_groups[env_name] = set()
    inventory_groups[env_name].add(host_name)

# 3. 生成Inventory格式内容并保存
with open('inventory.ini', 'w', encoding='utf-8') as f:
    for env, hosts in inventory_groups.items():
        f.write(f'[{env}]\n')
        # 按主机名排序后写入
        for host in sorted(hosts):
            f.write(f'{host}\n')

print("Inventory文件已生成:inventory.ini")

运行脚本后,同样会生成标准的按环境分组的Inventory文件。


对原有尝试的说明

你之前的Ansible任务仅处理了单个主机条目(var2的三个元素),没有遍历所有行数据,也未做去重和分组操作,因此无法生成完整的分组清单。上述方案解决了这些问题,实现了从原始数据到最终Inventory的完整流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:37:57