如何在system_users非空时执行Ansible的with_items任务?
解决Ansible中system_users为空时任务执行报错的问题
问题场景
原Ansible任务代码:
- name: "Add sudoers users to wheel group" with_items: "{{ system_users }}" changed_when: no user: name: "{{ item.name }}" password: "{{ item.password | password_hash('sha512') }}" groups: wheel append: yes state: present create_home: yes
当设置变量为空定义时:
system_users:
执行playbook出现报错:
fatal: [integration]: FAILED! => msg: |- The task includes an option with an undefined variable. The error was: 'None' has no attribute 'name'. 'None' has no attribute 'name'
尝试修改with_items为with_items: "{{ system_users | default([]) }}",仍报错:
fatal: [integration]: FAILED! => msg: |- The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'. 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'
添加条件when: system_users | length > 0后,依旧报错:
fatal: [integration]: FAILED! => msg: |- The conditional check 'system_users | length > 0' failed. The error was: Unexpected templating type error occurred on ({% if system_users | length > 0 %} True {% else %} False {% endif %}): object of type 'NoneType' has no len(). object of type 'NoneType' has no len()
解决方案
修改任务,同时使用带强制替换的default过滤器和长度判断条件:
- name: "Add sudoers users to wheel group" with_items: "{{ system_users | default([], true) }}" when: (system_users | default([], true)) | length > 0 changed_when: no user: name: "{{ item.name }}" password: "{{ item.password | password_hash('sha512') }}" groups: wheel append: yes state: present create_home: yes
原理说明
default([], true)的作用:
Ansible的default过滤器默认仅在变量未定义时生效,添加第二个参数true后,会强制替换所有空值场景(包括变量被定义为None、空字符串等)为空列表,避免遍历非列表类型的变量。- 双重保险的条件判断:
在when条件中先通过同样的default([], true)处理变量,再判断长度,避免None或空字符串无法调用len()的错误。当system_users为空列表时,with_items不会遍历任何项,同时when条件不满足,任务会被跳过。
内容的提问来源于stack exchange,提问作者Sangria
相关产品推荐
相关产品推荐

