Ansible中实现循环嵌套推荐使用loop + product过滤器(2.5+),生成笛卡尔积组合,通过item[0]、item[1]等取值;旧式with_nested仍可用但已弃用;同位置配对应使用zip而非product。

在 Ansible Playbook 中实现循环嵌套,核心是让多个列表按笛卡尔积方式组合遍历,比如为每个用户批量授权多个数据库、为每组文件路径创建多级目录结构等。Ansible 提供了明确的语法支持,但要注意版本差异和推荐用法。
用 loop + product(Ansible 2.5+ 推荐方式)
现代写法使用 loop 关键字配合 Jinja2 的 product 过滤器,语义清晰、兼容性好、易读性强:
- 语法结构:
loop: "{{ list1 | product(list2, list3) | list }}" -
product生成所有可能的元组组合,结果是二维列表,如[['A','a'], ['A','b'], ['B','a'], ['B','b']] - 在任务中通过
{{ item[0] }}、{{ item[1] }}分别取值
示例:批量创建用户并为其在多个数据库赋权
- name: Grant DB privileges to usersmysql_user:
name: "{{ item[0] }}"
priv: "{{ item[1] }}.*:ALL"
password: "secret"
loop: "{{ ['alice', 'bob'] | product(['appdb', 'logdb', 'auditdb']) | list }}"
用 with_nested(旧语法,仍可用但已弃用)
这是 Ansible 2.5 之前的标准嵌套方式,现在仍能运行,但官方建议迁移到 loop + product:
- 接受多个独立列表作为参数,自动做全量交叉
-
item[0]对应第一个列表元素,item[1]对应第二个,依此类推 - 不支持变量直接内联,需用
"{{ users }}"等引用变量
示例:在远程主机上创建三层嵌套目录
- name: Create nested directoriesfile:
path: "/opt/{{ item[0] }}/{{ item[1] }}/{{ item[2] }}"
state: directory
with_nested:
- ['web', 'api', 'db']
- ['prod', 'staging']
- ['logs', 'conf', 'data']
注意匹配长度与并行需求
如果目标是“同位置配对”(如 ['a','b','c'] 和 ['1','2','3'] 组成 a-1、b-2、c-3),不要用嵌套,而该用:
-
loop: "{{ list1 | zip(list2) | list }}"(推荐) - 或旧式
with_together(已弃用) - 当两列表长度不一致时,短列表末尾会补
null,需在模板中加判断避免报错
调试嵌套循环的小技巧
嵌套层级多时容易混淆索引,建议:
- 先用
debug任务打印{{ item }}查看实际结构 - 给
loop变量起有意义的名称,比如loop: "{{ users | product(dbs) | list }}"比硬编码更易维护 - 结合
vars提前定义列表,提升可读性和复用性











