如何使用Ansible解析CSV批量生成服务器ifcfg网络接口配置文件
解决方法
推荐优先使用Ansible官方的read_csv模块处理CSV文件,避免手动分割出现的格式、空格处理等问题,完整实现步骤如下:
步骤1:调整CSV文件格式
先给CSV增加表头行,明确每列字段含义,方便后续直接调用:
location,ansible_host,eth0_ip,ens3_ip New Orleans, 192.168.10.42, 13, 192.168.3.10 Atlanta, 192.168.31.100, 18, 192.168.10.10 Detroit, 172.16.31.8, 43, 172.16.10.27
表头对应你原CSV的四列含义:位置、服务器管理IP、eth0的IP地址、ens3的IP地址。
步骤2:编写Ansible Playbook
完整Playbook代码如下:
--- - name: 生成并推送网卡配置 hosts: localhost gather_facts: no tasks: - name: 读取CSV文件内容 community.general.read_csv: path: ./server_ips.csv strip: yes # 自动去除每个字段前后的多余空格 register: csv_records - name: 循环处理每台服务器配置 loop: "{{ csv_records.list }}" loop_control: loop_var: row vars: # 提前定义网卡配置模板 eth0_config: | TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none NM_CONTROLLED=no IPADDR={{ row.eth0_ip }} ens3_config: | TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none NM_CONTROLLED=no IPADDR={{ row.ens3_ip }} block: - name: 创建本地配置存储目录 file: path: "./tmp_config/{{ row.ansible_host }}" state: directory recurse: yes delegate_to: localhost - name: 生成本地ifcfg-eth0配置文件 copy: content: "{{ eth0_config }}" dest: "./tmp_config/{{ row.ansible_host }}/ifcfg-eth0" mode: '0644' delegate_to: localhost - name: 生成本地ifcfg-ens3配置文件 copy: content: "{{ ens3_config }}" dest: "./tmp_config/{{ row.ansible_host }}/ifcfg-ens3" mode: '0644' delegate_to: localhost - name: 推送网卡配置到目标服务器 vars: ansible_host: "{{ row.ansible_host }}" # 可补充SSH连接配置:ansible_ssh_user: root、ansible_ssh_pass等 block: - name: 拷贝ifcfg-eth0到目标路径 copy: src: "./tmp_config/{{ row.ansible_host }}/ifcfg-eth0" dest: "/etc/sysconfig/network-scripts/ifcfg-eth0" mode: '0644' - name: 拷贝ifcfg-ens3到目标路径 copy: src: "./tmp_config/{{ row.ansible_host }}/ifcfg-ens3" dest: "/etc/sysconfig/network-scripts/ifcfg-ens3" mode: '0644' - name: 重启网络服务生效 service: name: network state: restarted
可选:无表头手动分割方法
如果不想修改CSV加表头,可以用split加trim过滤器直接提取字段,示例如下:
- name: 手动分割CSV行提取字段 debug: msg: "eth0 IP为{{ fields[2] }}, ens3 IP为{{ fields[3] }}" loop: "{{ lookup('file', './file.one').splitlines() }}" vars: fields: "{{ item.split(',') | map('trim') | list }}"
直接通过fields[索引]即可取到对应列的标量值使用。
注意事项
- 如果系统使用NetworkManager管理网络,重启服务的
name参数改为NetworkManager即可 - 提前确认目标服务器的网卡配置路径,部分系统路径可能存在差异
内容的提问来源于stack exchange,提问作者user3423536
相关产品推荐
相关产品推荐

