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

Ansible条件判断中如何遍历列表匹配节点类型创建用户

问题背景

现有两台主机,分别对应生产环境、测试环境。节点类型标识test、prod配置在目标主机的本地事实文件中,对应ini配置分两类:
生产节点配置:

[node]
type= prod 

测试节点配置:

[node]
type= test

预先定义的用户配置变量如下:

users:
  - username: A
    password: password_A
    update_password: always
    home: /home/A
    state: present
    nodes: ['test', 'prod']

  - username: B 
    password: passwd_B
    update_password: always
    home: /home/B
    state: present
    nodes: ['test']

需求为:用户A需要在生产、测试主机上均完成创建,用户B仅在测试主机创建。
原有编写的角色任务在nodes字段为单值时可正常运行,原任务代码:

- name: create users
  ansible.builtin.user:
    name: "{{ item.username }}"
    password: "{{ item.password }}"
    uid: "{{ item.uid }}"
    home: "{{ item.home }}"
    create_home: yes
    group : "{{ item.group }}"
    shell: /bin/bash
    state: present
    expires: -1
  with_items:
      - "{{ users }}"
  when:  item.nodes  ==  ansible_local['myfact']['node"']['type']

现存问题:原有判断逻辑仅支持nodes为单值的匹配场景,无法适配nodes为多值列表的比对需求,后续还会新增除prod、test之外的其他主机类型,曾尝试使用subelements实现该逻辑但未成功。

解决方案

无需遍历item.nodes列表做逐值比对,直接使用Ansible内置的in测试判断当前节点类型是否在用户的允许节点列表中即可,逻辑简洁且后续新增节点类型无需调整任务代码。
首先修正原有代码的两处问题:

  • 原when条件中事实取值存在笔误:ansible_local['myfact']['node"']['type']多了冗余双引号,正确取值为ansible_local['myfact']['node']['type']
  • 等值判断替换为成员判断,无需额外嵌套循环或复杂插件调用。

修正后的可直接运行的任务代码:

- name: create users
  ansible.builtin.user:
    name: "{{ item.username }}"
    password: "{{ item.password }}"
    uid: "{{ item.uid | default(omit) }}"
    home: "{{ item.home }}"
    create_home: yes
    group : "{{ item.group | default(omit) }}"
    shell: /bin/bash
    state: present
    expires: -1
    update_password: "{{ item.update_password }}"
  loop: "{{ users }}"
  when: ansible_local['myfact']['node']['type'] in item.nodes

逻辑说明

  • 任务执行时会先获取当前主机的节点类型,直接判断该类型是否存在于当前遍历用户的nodes允许列表中,存在则执行用户创建操作,不存在则跳过,天然支持多节点类型的匹配需求
  • 代码中补充了default(omit)配置:原有用户变量中未定义uid、group字段,直接引用会触发变量未定义报错,添加该配置后如果对应字段未传值,将自动使用模块默认值
  • 补充了原任务遗漏的update_password参数,和预定义的变量配置对齐,保证密码更新逻辑生效

如果需要使用subelements实现(适配后续更复杂的列表嵌套场景),可参考如下写法,效果与上述方案完全一致:

- name: create users (subelements实现版本)
  ansible.builtin.user:
    name: "{{ item.0.username }}"
    password: "{{ item.0.password }}"
    uid: "{{ item.0.uid | default(omit) }}"
    home: "{{ item.0.home }}"
    create_home: yes
    group : "{{ item.0.group | default(omit) }}"
    shell: /bin/bash
    state: present
    expires: -1
    update_password: "{{ item.0.update_password }}"
  loop: "{{ users | subelements('nodes') }}"
  when: item.1 == ansible_local['myfact']['node']['type']

注意:subelements写法会将每个用户按nodes列表拆分为多条循环项,例如用户A会被拆为(A, test)、(A, prod)两个循环项,仅当循环项的第二个元素和当前节点类型匹配时才会执行操作。该写法循环次数更多,当前场景下直接使用in做成员判断是最优方案。

内容的提问来源于stack exchange,提问作者Philippe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:28:03