Ansible, only disable existing users?
Solution 1:
Q: "Only existing users can be disabled."
A: To modify present users only, use getent to read /etc/passwd and create a list of present users. Then use it in the condition. For example
- getent:
database: passwd
- set_fact:
users_present: "{{ getent_passwd.keys()|list }}"
- name: "disable user {{ item.name }}"
user:
name: "{{ item.name }}"
shell: /sbin/nologin
loop: "{{ users }}"
when:
- item.name in users_present
- item.state|default('present') == 'absent'
Note1: It's more robust to default state to 'present' instead of testing the existence of the attribute
- name: "create account for {{ item.name }}"
user:
name: "{{ item.name }}"
create_home: no
shell: /bin/bash
loop: "{{ users }}"
when: item.state|default('present') != 'absent'
Note2: The module user doesn't complain that a 'name' isn't present when 'state=absent'. Hence, it's not necessary to test the presence of a user in this case. Simply disable the user. For example
- name: "disable user {{ item.name }}"
user:
name: "{{ item.name }}"
state: absent
loop: "{{ users }}"
when: item.state|default('present') == 'absent'
Solution 2:
You can check if a user exists with getent
with getent passwd {{ item }}
.
Below is an example playbook:
---
- name: "Check if User exists sample"
hosts: localhost
connection: local
vars:
users:
- nginx
- root
- user4
- user3
tasks:
- name: "check for user in /etc/passwd"
command: getent passwd {{ item }}
register: check_user
ignore_errors: yes
loop: "{{ users }}"
register: all_checks
- name: "iterate over checks"
debug:
msg:
- "{{ item.rc }}"
- "{{ item.item }}"
when:
- item.rc == 0
loop: "{{ all_checks.results }}"
So in your case you need to modify the section of your playbook you posted like this:
tasks:
- name: "check for user in /etc/passwd"
command: getent passwd {{ item }}
register: check_user
ignore_errors: yes
loop: "{{ users }}"
register: all_checks
- name: "iterate over checks"
user:
name: "{{item.item}}"
shell: "/sbin/nologin"
when:
- item.state is defined and item.state == "absent"
- item.rc == 0
loop: "{{ all_checks.results }}"