Ansible – How to Disable Existing Users

ansible

I have a list of users in a yaml files, with a flag: state.

If the flag is undefined or if it is != "absent", I create the user :

    - name: "create account for {{item.name}}"
      user:
        name: "{{item.name}}"
        create_home: no
        shell: "/bin/bash"
      loop: "{{users}}"
      when:
      - item.state is undefined or item.state != "absent"

and on the contrary, I disallow "absent" users to connect:

    - name: "disable user {{item.name}}"
      user:
        name: "{{item.name}}"
        shell: "/sbin/nologin"
      loop: "{{users}}"
      when:
        - item.state is defined and item.state == "absent"

But How can I make it so that only existing users can be disabled ? (And not creating a user to set its shell as /sbin/nologin)

Best Answer

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'