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

如何从文本文件生成YAML/JSON并按条件生成Ansible清单?

问题描述

现有input.txt文件包含以下格式的服务器信息:

it-linux1,p,a,3,3
it-test2,p,a,1,3
it-test3-dev,t,e,3,2
it-linux4,p,a,1,1
it-windows,t,e,3,4

当前使用的Ansible Playbook仅能读取文件内容并生成output.yaml(内容如下),但需要进一步处理,生成满足特定筛选条件的服务器清单,比如:

  • 筛选包含p值的服务器
  • 筛选同时包含t和3值的服务器
  • 筛选包含p且包含3值的服务器
  • 筛选包含p且包含1值的服务器

当前Playbook内容:

- name: Simple Read file and output JSON
  hosts: localhost
  connection: local
  become: false
  tasks:
  - name: Read Data File
    set_fact:
      data: "{{ lookup('ansible.builtin.file', '/home/checkout/myProjects/input.txt').split('\n') }}"

  - name: Show debug data
    ansible.builtin.debug: var=data

  - name: Create a new array
    set_fact:
      data_elements: []

  - name: Loop through lines and add data elements to array
    set_fact:
      data_elements: "{{ data_elements + [item] }}"
    loop: "{{ data }}"

  - name: Show debug data
    ansible.builtin.debug: var=data_elements

  - name: Write output YAML file
    copy:
      dest: output.yaml
      content: "{{ {'records': data_elements} | to_nice_yaml }}"

生成的output.yaml内容:

records:
- it-linux1,p,a,3,3
- it-test2,p,a,3,3
- it-test3-dev,t,e,1,2
- it-linux4,p,a,3,1
- it-windows,t,e,3,4

需求:能否读取并处理output.yaml(或直接处理原始input.txt),生成符合上述筛选条件的服务器清单?


解决方案

不需要先生成output.yaml再处理,直接在Playbook中解析原始input.txt的每行数据,拆分字段后进行条件筛选更高效。以下是实现不同筛选需求的Playbook示例:

1. 解析原始数据并拆分字段

首先将每行数据按逗号拆分为字段数组,方便后续条件判断:

- name: Generate filtered Ansible inventories
  hosts: localhost
  connection: local
  become: false
  vars:
    input_file_path: "/home/checkout/myProjects/input.txt"
  tasks:
    - name: Read and parse input file
      set_fact:
        parsed_servers: "{{ lookup('file', input_file_path).split('\n') | reject('equalto', '') | map('split', ',') | list }}"
      # 逻辑说明:
      # - split('\n'): 按行拆分文件内容
      # - reject('equalto', ''): 移除空行
      # - map('split', ','): 将每行按逗号拆分为字段数组

2. 实现不同筛选条件

筛选包含p值的服务器

- name: Filter servers with 'p' value
      set_fact:
        servers_with_p: "{{ parsed_servers | select('contains', 'p') | map('first') | list }}"
      # 逻辑说明:
      # - select('contains', 'p'): 保留包含'p'的字段数组
      # - map('first'): 提取每个数组的第一个元素(服务器名称)

    - name: Write 'p' servers to inventory file
      copy:
        dest: inventory_p.yaml
        content: |
          [servers_with_p]
          {% for server in servers_with_p %}
          {{ server }}
          {% endfor %}

筛选同时包含t和3值的服务器

- name: Filter servers with 't' and '3' values
      set_fact:
        servers_with_t_and_3: "{{ parsed_servers | select('contains', 't') | select('contains', '3') | map('first') | list }}"

    - name: Write 't+3' servers to inventory file
      copy:
        dest: inventory_t_3.yaml
        content: |
          [servers_with_t_and_3]
          {% for server in servers_with_t_and_3 %}
          {{ server }}
          {% endfor %}

筛选包含p且包含3值的服务器

- name: Filter servers with 'p' and '3' values
      set_fact:
        servers_with_p_and_3: "{{ parsed_servers | select('contains', 'p') | select('contains', '3') | map('first') | list }}"

    - name: Write 'p+3' servers to inventory file
      copy:
        dest: inventory_p_3.yaml
        content: |
          [servers_with_p_and_3]
          {% for server in servers_with_p_and_3 %}
          {{ server }}
          {% endfor %}

筛选包含p且包含1值的服务器

- name: Filter servers with 'p' and '1' values
      set_fact:
        servers_with_p_and_1: "{{ parsed_servers | select('contains', 'p') | select('contains', '1') | map('first') | list }}"

    - name: Write 'p+1' servers to inventory file
      copy:
        dest: inventory_p_1.yaml
        content: |
          [servers_with_p_and_1]
          {% for server in servers_with_p_and_1 %}
          {{ server }}
          {% endfor %}

3. 基于output.yaml的处理方案(可选)

如果必须从已生成的output.yaml读取数据处理,可先读取该文件,再解析处理:

- name: Read output.yaml
      set_fact:
        output_data: "{{ lookup('file', 'output.yaml') | from_yaml }}"

    - name: Parse records from output.yaml
      set_fact:
        parsed_output_servers: "{{ output_data.records | reject('equalto', '') | map('split', ',') | list }}"

    # 后续筛选逻辑和上述一致,比如筛选含p和3的服务器:
    - name: Filter servers with 'p' and '3' from output.yaml
      set_fact:
        servers_p_3_from_output: "{{ parsed_output_servers | select('contains', 'p') | select('contains', '3') | map('first') | list }}"

示例生成结果

以inventory_p_3.yaml为例,最终内容会是:

[servers_with_p_and_3]
it-linux1
it-test2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:22:49