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

如何通过Ansible实现文件与对应主机的逐一复制?

问题

需要将10个文件按一一对应关系复制到10台主机,例如1_file.txt复制到1_host,2_file.txt复制到2_host,以此类推。

尝试过两种方法均报错:

  1. 使用zip过滤器的Playbook:
- name: Copy splitted files to instances
  copy:
    src: "{{ item.0 }}"
    dest: "{{ remote_ips_file }}"
  delegate_to: "{{ item.1 }}"
  loop: "{{ splitted_files.files | zip(instances) | list }}"

报错信息:

{"msg": "Unexpected failure during module execution.", "stdout": ""}
  1. 调用zip()函数的写法:
- name: Copy files to hosts
  hosts: "{{ hosts }}"
  tasks:
  - name: Copy file to host
    copy:
      src: "{{ item.0 }}"
      dest: "/tmp/{{ item.1 }}"
    loop: "{{ zip(files, hosts) }}"

vars:
  files: ['/path/to/file1', '/path/to/file2']
  hosts: ['host1', 'host2']

报错信息:

zip is undefined

临时解决方法使用with_together,但无法并行执行:

- name: Copy splitted files to instances
  copy:
    src: "{{ item.0.path }}"
    dest: "{{ remote_ips_file }}"
  delegate_to: "{{ item.1 }}"
  with_together:
    - "{{ splitted_files.files }}"
    - "{{groups['all']}}"
错误原因
  1. 直接调用zip()函数报错:Ansible的Jinja2模板环境中没有内置zip函数,必须通过管道过滤器的方式使用zip(即list1 | zip(list2))。
  2. 第一种zip过滤器写法报错:splitted_files.files是文件对象列表(通常由find模块返回),每个元素是包含path等属性的字典,直接使用item.0会传递整个对象而非文件路径,导致模块执行失败。
  3. with_together无法并行:这是旧版循环语法的特性,默认串行执行;而loop是Ansible推荐的新语法,支持并行执行(依赖forks配置)。
正确实现方式

以下两种方法均支持并行执行,且能保证文件与主机的一一对应:

方法1:修正zip过滤器的路径引用

- name: 按对应关系复制文件到主机
  copy:
    src: "{{ item.0.path }}"  # 取文件对象的path属性作为源路径
    dest: "{{ remote_ips_file }}"
  delegate_to: "{{ item.1 }}"
  loop: "{{ splitted_files.files | zip(groups['all']) | list }}"
  # 若使用自定义主机列表,替换groups['all']为你的instances变量

说明:

  • 确保splitted_files.files和主机列表(如groups['all'])长度完全一致
  • Ansible默认并行数由forks参数控制(默认5,可在ansible.cfg中调整为10以匹配你的主机数量)

方法2:利用循环索引匹配

通过循环的索引值直接对应文件和主机,逻辑更直观:

- name: 按索引对应复制文件到主机
  copy:
    src: "{{ splitted_files.files[ansible_loop.index0].path }}"
    dest: "{{ remote_ips_file }}"
  delegate_to: "{{ groups['all'][ansible_loop.index0] }}"
  loop: "{{ groups['all'] }}"
  loop_control:
    extended: yes  # 开启扩展循环变量,才能使用ansible_loop.index0

说明:

  • ansible_loop.index0是从0开始的循环索引,确保第N个循环对应第N个文件和第N台主机
  • 同样需要保证文件列表与主机列表长度一致
关键注意事项
  • 始终确保文件列表和主机列表的长度相同,否则会出现匹配错位或执行报错
  • 若需要全并行执行,将ansible.cfg中的forks值设置为等于或大于主机数量(如forks=10)
  • 使用delegate_to时,控制节点需能SSH访问所有目标主机,且拥有文件复制的权限

内容的提问来源于stack exchange,提问作者Сергей Гусев

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:50:19