如何在Ansible中获取本地模板目录的非递归子目录列表?
解决Ansible本地模板目录一级子目录遍历问题
要获取Ansible角色templates/sites下的一级子目录并处理其中的模板文件,可通过本地lookup结合路径处理实现,避开你提到的几种方法的缺陷,具体方案如下:
核心思路
利用fileglob lookup在本地匹配templates/sites下一级子目录中的所有文件,提取每个文件的父目录并去重,得到准确的一级子目录列表;再基于该列表完成模板渲染或其他操作。
具体实现步骤
1. 获取一级子目录列表
先通过set_fact存储提取到的子目录:
- name: 提取templates/sites下的一级子目录 set_fact: site_subdirs: "{{ lookup('fileglob', 'roles/your_role/templates/sites/*/*', wantlist=True) | map('dirname') | unique }}"
lookup('fileglob', ...):在本地匹配templates/sites下所有一级子目录中的文件(*/*确保只匹配一级子目录内的文件,不会递归更深)map('dirname'):提取每个文件的父目录路径unique:去重后得到唯一的一级子目录列表(如bar、baz、foo对应的完整路径)
2. 遍历子目录处理模板文件
如果需要先创建远程对应目录,再渲染模板:
- name: 创建远程站点目录 file: path: "/remote/target/sites/{{ item | basename }}" state: directory mode: '0755' loop: "{{ site_subdirs }}" - name: 渲染子目录内的模板文件到远程 template: src: "{{ file_item }}" dest: "/remote/target/{{ file_item | regex_replace('^roles/your_role/templates/', '') }}" mode: '0644' loop: "{{ lookup('fileglob', '{{ item }}/*', wantlist=True) }}" loop_control: loop_var: file_item with_items: "{{ site_subdirs }}"
如果不需要单独处理目录,可直接遍历所有目标模板文件完成渲染:
- name: 直接渲染sites下一级子目录的所有模板 template: src: "{{ item }}" dest: "/remote/target/{{ item | regex_replace('^roles/your_role/templates/', '') }}" mode: '0644' loop: "{{ lookup('fileglob', 'roles/your_role/templates/sites/*/*', wantlist=True) }}"
方案优势
- 完全在本地执行路径匹配,不会像
find模块默认去远程主机查找 - 仅匹配一级子目录内的文件,不会递归遍历更深层级,也不会出现
filetree的大量跳过提示 - 避开
with_fileglob无法识别目录的问题,通过文件反向推导目录,结果准确
内容的提问来源于stack exchange,提问作者Stephen Ostermiller
相关产品推荐
相关产品推荐

