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

Ansible读取CSV渲染模板异常:所有服务器均应用最后一行数据

问题:Ansible渲染模板时所有服务器均应用CSV最后一行数据

我通过CSV文件获取数据,用Ansible渲染模板后复制到远程服务器,但每台服务器都会遍历整个CSV文件,最终所有服务器的配置文件都只应用了CSV的最后一行数据,而非对应行的数据。

相关文件内容

test.csv

Application,env,Datacenter,Hostname
Microsoft,Test,DC1,testserver1
Apple,Test,DC2,testserver2

原main.yml

- name: read csv
  read_csv:
    path: /u00/app/monitor/test.csv
    key: Hostname
  register: newrelic

- name: Print newrelic var
  ansible.builtin.debug:
    var: newrelic.dict[inventory_hostname]

- name: copy template
  template:
    src: /u00/ansible/Playbooks/files/infra-config.yml_template
    dest: /u00/app/monitor/infra-config.yml
  loop: "{{ newrelic.list }}"

- name: Start the New Relic Service
  ansible.builtin.systemd:
    name: newrelic-infra.service
    state: started
  become: yes
  become_user: root

模板文件infra-config.yml_template

custom_attributes:
    application : {{ item.Application }}
    env : {{ item.env }}
    datacenter : {{ item.Datacenter }}
log:
 file: /u00/app/monitor/infra.log

预期与实际结果

预期结果

testserver1应用CSV第一行数据,testserver2应用第二行数据:

# ssh admin@testserver1
cat infra-config.yml

custom_attributes:
    application : Microsoft
    env : Test
    datacenter : DC1
log:
 file: /u00/app/monitor/infra.log

# ssh admin@testserver2
cat infra-config.yml

custom_attributes:
    application : Apple
    env : Test
    datacenter : DC2
log:
 file: /u00/app/monitor/infra.log

实际结果

所有服务器均应用CSV最后一行数据:

# ssh admin@testserver1
cat infra-config.yml

custom_attributes:
    application : Apple
    env : Test
    datacenter : DC2
log:
 file: /u00/app/monitor/infra.log

# ssh admin@testserver2
cat infra-config.yml

custom_attributes:
    application : Apple
    env : Test
    datacenter : DC2
log:
 file: /u00/app/monitor/infra.log

问题原因

原Playbook中使用loop: "{{ newrelic.list }}"遍历整个CSV条目列表,导致每台服务器都会执行多次模板复制操作,后一次写入的内容会覆盖前一次,最终所有服务器的配置文件都保留了CSV最后一行的数据。

实际上你已经通过key: Hostname参数将CSV数据转换为以主机名为键的字典newrelic.dict,完全可以直接匹配当前服务器的主机名,获取对应的数据条目,不需要遍历整个列表。

修正后的Playbook

修改copy template任务,去掉loop,直接引用当前主机对应的CSV条目:

- name: read csv
  read_csv:
    path: /u00/app/monitor/test.csv
    key: Hostname
  register: newrelic

- name: Print newrelic var
  ansible.builtin.debug:
    var: newrelic.dict[inventory_hostname]

- name: copy template
  template:
    src: /u00/ansible/Playbooks/files/infra-config.yml_template
    dest: /u00/app/monitor/infra-config.yml
  vars:
    item: "{{ newrelic.dict[inventory_hostname] }}"

- name: Start the New Relic Service
  ansible.builtin.systemd:
    name: newrelic-infra.service
    state: started
  become: yes
  become_user: root

另一种修改方式(调整模板)

也可以直接修改模板中的变量引用,不需要在任务里定义item变量:

custom_attributes:
    application : {{ newrelic.dict[inventory_hostname].Application }}
    env : {{ newrelic.dict[inventory_hostname].env }}
    datacenter : {{ newrelic.dict[inventory_hostname].Datacenter }}
log:
 file: /u00/app/monitor/infra.log

对应的任务简化为:

- name: copy template
  template:
    src: /u00/ansible/Playbooks/files/infra-config.yml_template
    dest: /u00/app/monitor/infra-config.yml

验证结果

修正后,每台服务器会根据自身主机名匹配CSV中的对应条目,生成符合预期的配置文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:01:27