How to Remove a User Account with Ansible

The ansible.builtin.user module with state: absent removes user accounts from Linux, macOS, and FreeBSD systems. Add remove: true to also delete the home directory and mail spool.

Quick Example

- name: Remove user 'example' and their home directory
  ansible.builtin.user:
    name: example
    state: absent
    remove: true
  become: true

Parameters for User Removal

ParameterTypeDefaultDescription
namestring—Username to remove (required)
statestringpresentSet to absent to delete
removebooleanfalseRemove home dir and mail spool
forcebooleanfalseForce removal even if user is logged in

Remove User and Home Directory

- name: Delete user and all their files
  ansible.builtin.user:
    name: john
    state: absent
    remove: true
  become: true

This is equivalent to running userdel --remove john on Linux.

What gets removed:

  • Home directory (e.g., /home/john)
  • Mail spool (e.g., /var/mail/john)
  • User entry from /etc/passwd and /etc/shadow
  • Group entry if it was a user-private group

What does NOT get removed:

  • Files owned by the user outside their home directory
  • Cron jobs (remove separately)
  • systemd user services

Remove User Without Deleting Files

- name: Remove user account but keep home directory
  ansible.builtin.user:
    name: john
    state: absent
  become: true

Force Remove Logged-In User

- name: Force remove user even if logged in
  ansible.builtin.user:
    name: john
    state: absent
    remove: true
    force: true
  become: true

⚠️ Use with caution — forcing removal of a logged-in user can cause data loss.

Remove Multiple Users

- name: Remove multiple users
  ansible.builtin.user:
    name: "{{ item }}"
    state: absent
    remove: true
  loop:
    - olduser1
    - olduser2
    - contractor3
  become: true

Remove Users Not in a List

- name: Get existing users
  ansible.builtin.getent:
    database: passwd

- name: Remove unauthorized users
  ansible.builtin.user:
    name: "{{ item.key }}"
    state: absent
    remove: true
  loop: "{{ getent_passwd | dict2items }}"
  when:
    - item.value[1] | int >= 1000
    - item.value[1] | int < 65000
    - item.key not in allowed_users
  become: true
  vars:
    allowed_users:
      - alice
      - bob
      - deploy

Also Clean Up Cron Jobs

- name: Remove user cron jobs
  ansible.builtin.cron:
    name: "{{ item }}"
    user: john
    state: absent
  loop:
    - "backup job"
    - "log rotation"

- name: Remove user account
  ansible.builtin.user:
    name: john
    state: absent
    remove: true
  become: true

Full Offboarding Playbook

---
- name: Offboard user
  hosts: all
  become: true
  vars:
    offboard_user: john
  tasks:
    - name: Kill user processes
      ansible.builtin.command:
        cmd: "pkill -u {{ offboard_user }}"
      ignore_errors: true

    - name: Remove from sudoers
      ansible.builtin.lineinfile:
        path: /etc/sudoers.d/{{ offboard_user }}
        state: absent
      ignore_errors: true

    - name: Remove SSH authorized keys
      ansible.builtin.file:
        path: "/home/{{ offboard_user }}/.ssh/authorized_keys"
        state: absent

    - name: Remove user and home directory
      ansible.builtin.user:
        name: "{{ offboard_user }}"
        state: absent
        remove: true

Windows Users

For Windows hosts, use ansible.windows.win_user:

- name: Remove Windows user
  ansible.windows.win_user:
    name: john
    state: absent

Platform Commands Used

PlatformCommand
Linuxuserdel / userdel --remove
FreeBSDpw userdel
macOSdscl . -delete /Users/john
Windowsansible.windows.win_user module

Conclusion

Use ansible.builtin.user with state: absent and remove: true to cleanly remove user accounts and their home directories. For full offboarding, also clean up cron jobs, sudo access, and SSH keys.

code with ❤️ in GitHub