You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible如何使用嵌套循环匹配两个用户列表并设置包含状态的新事实

Ansible 合并两个用户列表实现方案

可以实现需求,不需要写复杂的嵌套循环,使用Ansible自带的过滤器即可快速完成匹配,以下是可直接运行的实现代码:

方案1:单循环+过滤器实现(适合小数据量)

- name: 合并用户角色与账号锁定状态生成新事实
  set_fact:
    my_new_list: "{{ my_new_list | default([]) + [ item | combine({'isLockedOut': matched_status.isLockedOut | default('Name Does not Match')}) ] }}"
    cacheable: yes
  loop: "{{ username_and_role }}"
  vars:
    # 从状态列表中筛选和当前遍历用户Name一致的条目
    matched_status: "{{ username_and_status | selectattr('Name', 'equalto', item.Name) | first | default({}) }}"

输出示例

最终生成的my_new_list格式如下:

[
  {
    "Name": "Jack",
    "Role": "Admin User",
    "isLockedOut": "no"
  },
  {
    "Name": "Tom",
    "Role": "Buyer",
    "isLockedOut": "no"
  },
  {
    "Name": "Jill",
    "Role": "Seller",
    "isLockedOut": "no"
  }
]

方案2:预生成字典匹配(适合大数据量,性能更高)

如果两个列表数据量较大,可以先把状态列表转为以Name为key的字典,再做匹配,避免每次循环都遍历整个状态列表:

- name: 预生成账号状态查询字典
  set_fact:
    status_dict: "{{ status_dict | default({}) | combine({item.Name: item.isLockedOut}) }}"
  loop: "{{ username_and_status }}"

- name: 合并生成新的用户事实
  set_fact:
    my_new_list: "{{ my_new_list | default([]) + [ item | combine({'isLockedOut': status_dict[item.Name] | default('Name Does not Match')}) ] }}"
    cacheable: yes
  loop: "{{ username_and_role }}"

原代码错误原因

  1. 同时使用with_items和loop参数,二者是Ansible循环的不同写法,会产生参数冲突,只能保留一个
  2. 没有对my_new_list做累加处理,每次循环都会覆盖之前的结果,不会追加新条目
  3. 匹配逻辑中username变量未定义,也没有实现从username_and_status中筛选对应Name条目的逻辑

内容的提问来源于stack exchange,提问作者Hary Aprianto Ginting

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:24:03