如何让Ansible assemble仅在控制节点输出合并后的文件?
Ansible控制节点合并远程拉取文件的解决方案
问题描述
我需要用Ansible Playbook完成以下操作:
- 在远程主机
/tmp目录下创建以当前主机名命名的文件 - 将这些文件拉取到控制节点的指定目录
- 仅在控制节点将拉取的文件合并为一个文件,但使用
assemble模块时,合并后的文件被部署到了所有远程主机,如何解决?
原Playbook代码:
--- - block: - shell: | cd /tmp echo {{ inventory_hostname }} > {{ inventory_hostname }}-Info.txt - ansible.builtin.fetch: src: /tmp/{{ inventory_hostname }}-Info.txt dest: /tmp/gatheredFiles/ flat: yes # 问题:合并文件被创建到所有远程主机,而非控制节点 - ansible.builtin.assemble: src: /tmp/gatheredFiles dest: /tmp/combinedFile.txt delimiter: '######' remote_src: false # when: "'condition' in ansible_hostname"
解决方案
要让assemble仅在控制节点执行,有两种常用方法:
方法1:给assemble任务添加delegate_to: localhost
通过delegate_to: localhost指定该任务在控制节点执行,同时确保文件已存在于控制节点本地(remote_src: false为默认值,可省略):
修改后的Playbook:
--- - block: - shell: | cd /tmp echo {{ inventory_hostname }} > {{ inventory_hostname }}-Info.txt - ansible.builtin.fetch: src: /tmp/{{ inventory_hostname }}-Info.txt dest: /tmp/gatheredFiles/ flat: yes # 指定在控制节点执行合并操作 - ansible.builtin.assemble: src: /tmp/gatheredFiles dest: /tmp/combinedFile.txt delimiter: '######' delegate_to: localhost # when: "'condition' in ansible_hostname"
方法2:拆分Play,单独针对localhost执行合并
把合并任务放到一个只针对localhost的Play中,彻底和远程主机的任务分离:
--- # 第一部分:在远程主机创建文件并拉取到控制节点 - name: 在远程主机创建文件并拉取 hosts: all tasks: - shell: | cd /tmp echo {{ inventory_hostname }} > {{ inventory_hostname }}-Info.txt - ansible.builtin.fetch: src: /tmp/{{ inventory_hostname }}-Info.txt dest: /tmp/gatheredFiles/ flat: yes # 第二部分:仅在控制节点合并文件 - name: 在控制节点合并文件 hosts: localhost connection: local tasks: - ansible.builtin.assemble: src: /tmp/gatheredFiles dest: /tmp/combinedFile.txt delimiter: '######'
注意事项
- 使用
fetch的flat: yes时,需确保控制节点的/tmp/gatheredFiles目录已存在,可提前用file模块创建:- name: 创建控制节点存储目录 file: path: /tmp/gatheredFiles state: directory delegate_to: localhost - 如果未添加
flat: yes,拉取的文件会存放在/tmp/gatheredFiles/<主机名>/tmp/路径下,此时assemble的src参数需要对应调整为该路径。
内容的提问来源于stack exchange,提问作者Jiffy
相关产品推荐
相关产品推荐

