Ansible嵌套列表迭代:嵌套列表为空时使用父级默认值
解决方案:处理Ansible嵌套列表迭代,补全空列表默认值
要实现迭代包含嵌套ssh列表的users,且当ssh为空时使用父级字段作为默认值,需要先预处理用户数据,再用subelements遍历。
步骤1:预处理用户数据
先将每个用户的ssh字段处理为:
- 若
ssh不为空:为每个ssh条目补全缺失的username/state/role(用父级字段作为默认) - 若
ssh为空:生成一个包含父级username/state/role的条目列表
添加如下set_fact任务:
- name: 预处理用户数据,补全SSH条目默认值 set_fact: processed_users: "{{ processed_users | default([]) + [ user | combine({ 'ssh': user.ssh | default([]) | ternary( # SSH列表非空时,为每个条目合并父级默认字段 user.ssh | map('combine', user | dict2items | selectattr('key', 'in', ['username', 'state', 'role']) | items2dict) | list, # SSH列表为空时,生成包含父级字段的单条目列表 [ user | dict2items | selectattr('key', 'in', ['username', 'state', 'role']) | items2dict ] ) }) ] }}" loop: "{{ users }}"
步骤2:遍历处理后的数据
使用subelements遍历预处理后的processed_users,此时所有用户(包括ssh为空的Mario)都会被覆盖:
- name: 遍历所有SSH条目(含默认值条目) include_tasks: "mytasks.yml" loop: "{{ processed_users | subelements('ssh') }}" loop_control: loop_var: user_item when: users is defined
在子任务中使用数据
在mytasks.yml中,你可以通过以下方式访问数据:
user_item[0]:父级用户的完整数据(如name字段)user_item[1]:当前SSH条目(已补全默认值的username/state/role)
示例mytasks.yml内容:
- name: 打印SSH条目信息 debug: msg: "用户: {{ user_item[0].name }}, SSH用户名: {{ user_item[1].username }}, 角色: {{ user_item[1].role }}, 状态: {{ user_item[1].state }}"
原代码失效原因
- 第一个任务用
subelements(ssh)时,默认skip_missing=True,会直接跳过ssh为空的用户(如Mario) - 第二个任务的
default用法错误,user变量在loop定义前不可用,无法动态补全默认值
内容的提问来源于stack exchange,提问作者Kiwi
相关产品推荐
相关产品推荐

