如何实现Ansible with_fileglob递归遍历子目录或寻找替代方案
Ansible 递归遍历目录批量部署模板文件方案
with_fileglob 原生不支持递归匹配,这是模块本身的设计限制,以下是两种可直接落地的实现方式:
方案1:使用内置filetree lookup(推荐,Ansible 2.10+ 可用)
这是Ansible官方提供的专门用于递归遍历目录的插件,会自动返回遍历到的每个条目的类型、路径等信息,直接过滤出普通文件即可循环处理,不需要额外写shell命令:
- name: 递归渲染所有模板文件 ansible.builtin.template: src: "{{ item.src }}" # 若需要保留源目录结构,用下面的dest写法 dest: "{{ deploy_root }}/{{ item.path | regex_replace('\\.j2$', '') }}" # 如果不需要保留目录结构,要把所有文件平铺到目标目录,替换成下面的dest即可 # dest: "{{ deploy_root }}/{{ item.path | basename | regex_replace('\\.j2$', '') }}" loop: "{{ query('ansible.builtin.filetree', user_configs_path) }}" when: item.state == 'file' # 自动跳过目录、软链接,只处理普通文件
参数说明:
item.src:控制节点上模板文件的绝对路径,可直接传给template模块的src参数item.path:模板文件相对于你传入的user_configs_path的相对路径,方便在目标端复刻目录结构
方案2:本地find命令拉取文件列表(兼容低版本Ansible)
如果你的Ansible版本低于2.10,没有内置filetree插件,可以直接在控制节点执行find命令递归获取所有普通文件列表,再循环渲染:
- name: 递归查找控制节点上所有模板文件 ansible.builtin.shell: "find {{ user_configs_path }} -type f" delegate_to: localhost run_once: true register: template_file_list changed_when: false # 查找操作不会改动任何文件,固定返回ok状态 - name: 循环渲染模板到目标节点 ansible.builtin.template: src: "{{ item }}" dest: "{{ item | replace('.j2', '') | replace(user_configs_path, deploy_root) }}" loop: "{{ template_file_list.stdout_lines }}"
如果你不需要保留目录结构,dest参数改成
"{{ deploy_root }}/{{ item | basename | replace('.j2', '') }}"即可。
原任务不生效原因
你之前写的with_fileglob: "{{ user_configs_path }}/*"通配符只会匹配configs目录下第一级的条目,不会进入子目录递归查找,所以存放在二级、三级子目录下的配置文件完全不会被匹配到,任务执行自然没有任何效果。
内容的提问来源于stack exchange,提问作者Kristi Jorgji
相关产品推荐
相关产品推荐

