Ansible中map传递字典参数被识别为字符串的问题及成员列表替换
Ansible字典元素批量处理:更新members列表(交集/替换)
我有一个描述用户组的YAML字典,每个组包含members列表等字段。想要批量将每个组的members替换为原列表与指定新列表的交集,但使用map+combine时出现错误:
fatal: [localhost]: FAILED! => {"msg": "failed to combine variables, expected dicts but got a 'str' and a 'dict': \n"all"\n{"members": ["alice", "bob"]}"
问题原因
my_groups是字典类型,直接使用map过滤器时,默认会迭代字典的键字符串(如group1、group2),而非每个组对应的配置字典。这导致combine尝试将字符串与字典合并,触发类型不匹配的报错。
解决方案
要保留组名(字典的键)并处理每个组的配置(字典的value),可以通过以下步骤实现:
- 用
dict2items将字典转为键值对列表,方便迭代每个组的配置 - 对每个组的配置,按需更新members字段(取交集或直接替换)
- 用
combine将新的members字段合并到原组配置中 - 最后用
items2dict将处理后的键值对列表转回字典格式
完整Playbook代码
- hosts: localhost become: no vars: my_groups: group1: members: [alice, bob, john] comment: first group sudoers: yes group2: members: [alice, john] comment: second group sudoers: no new_users_list: [alice, bob] tasks: - name: 批量更新每个组的members(取原列表与新列表的交集) set_fact: updated_groups: >- {{ my_groups | dict2items | map('combine', { 'value': item.value | combine({ 'members': item.value.members | intersect(new_users_list) }) }) | items2dict }} loop: "{{ my_groups | dict2items }}" loop_control: label: "{{ item.key }}" - name: 输出处理后的用户组结构 debug: var: updated_groups
代码说明
dict2items:将my_groups字典转换为[{key: 'group1', value: {...}}, ...]的列表格式,便于迭代处理每个组intersect:计算原members列表与new_users_list的交集,实现用户期望的成员筛选效果combine:将新的members字段合并到原组配置中,保留其他字段(如comment、sudoers)不变items2dict:将处理后的键值对列表转回字典格式,恢复原有的用户组结构
替换members的简化版本
如果不需要取交集,而是直接将members替换为new_users_list,只需修改members字段的赋值:
'members': new_users_list
最终输出结果
执行后会得到符合预期的用户组结构:
updated_groups: group1: comment: first group members: - alice - bob sudoers: true group2: comment: second group members: - alice sudoers: false
内容的提问来源于stack exchange,提问作者Ulvida
相关产品推荐
相关产品推荐

