Ansible Enable User Account: Unlock & Activate Users Guide
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
How to enable and unlock user accounts with Ansible user module. Unlock passwords, set shells, manage account expiry, and bulk re-enable users.

How to Enable a user account with Ansible?
See also: Add Secondary Groups to Linux Users with Ansible Playbook
Ansible enable user account
Today we're talking about the Ansible moduleuser.
The full name is ansible.builtin.user, which means that is part of the collection of modules "builtin" with ansible and shipped with it.
It's a module pretty stable and out for years, it manages user accounts.
It supports a huge variety of Linux distributions, SunOS and macOS, and FreeBSD.
For Windows, use the ansible.windows.win_user module instead.
Parameters
- name string - username
- state string - present/absent
- password_lock boolean - no/yes
- shell string - "/bin/bash"
passwd tool to change a password by changing it to a value that matches no possible encrypted value (it adds a ´!´ at the beginning of the password). To enable our user obviously we need to disable this parameter.
The "shell" parameter specifies the user shell. Two very special are the nologin and false shell. Apply the value of "/bin/bash" is going to restore user access.
## Playbook Let's jump into a real-life Ansible Playbook to enable a user without password lock and with the appropriate shell.
code
- enable.yml
---
- name: user module Playbook
hosts: all
become: true
vars:
myuser: "example"
tasks:
- name: enable user
ansible.builtin.user:
name: "{{ myuser }}"
state: present
password_lock: false
shell: "/bin/bash"
output
$ ansible-playbook -i Playbook/inventory enable\ user\ account/user.yml
PLAY [user module Playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [enable user] ********************************************************************************
changed: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
verification
# getent passwd | grep example
example:x:1002:1002:Ansible example:/home/example:/bin/bash
# passwd -S example
example PS 2021-10-04 0 99999 7 -1 (Password set, SHA512 crypt.)
# grep example /etc/shadow
example:$6$mysecretsalt$MIJffjeQyfrKKrGkprGrDL/g2mCJa53koLmYQuuLmY9y37pDvGKPXU1Ov3RbMi.tpQ9cWvxAzUVtBLe7KrZoU.:18904:0:99999:7:::
See also: Ansible Linux Users and Groups: Complete Management Guide (Examples)
Conclusion
Now you know how to enable a user without a password lock and with the appropriate shell.
Enable a Locked Account
Unlock password
- name: Unlock user account
ansible.builtin.command: "usermod -U {{ username }}"
become: trueRemove account expiry
- name: Remove expiry date
ansible.builtin.user:
name: "{{ username }}"
expires: -1
become: trueFull re-enable (unlock + remove expiry + set shell)
- name: Fully re-enable user
ansible.builtin.user:
name: "{{ username }}"
expires: -1
shell: /bin/bash
become: true
- name: Unlock password
ansible.builtin.command: "usermod -U {{ username }}"
become: trueSee also: Change the User Primary Group on Linux with Ansible
Bulk Enable Users
- name: Re-enable returning contractors
block:
- ansible.builtin.user:
name: "{{ item }}"
expires: -1
shell: /bin/bash
- ansible.builtin.command: "usermod -U {{ item }}"
loop:
- contractor1
- contractor2
become: trueCheck Account Status
- name: Check if account is locked
ansible.builtin.command: "passwd -S {{ username }}"
register: passwd_status
changed_when: false
become: true
- name: Show status
debug:
msg: >
{{ username }} is {{ 'LOCKED' if 'L' in passwd_status.stdout.split()[1]
else 'ACTIVE' }}Enable vs Disable Comparison
# DISABLE (lock account)
- ansible.builtin.user:
name: departed_user
expires: 0 # Expire immediately
shell: /sbin/nologin
- command: "usermod -L departed_user"
# ENABLE (unlock account)
- ansible.builtin.user:
name: returning_user
expires: -1 # Remove expiry
shell: /bin/bash
- command: "usermod -U returning_user"Windows Enable
- name: Enable Windows account
ansible.windows.win_user:
name: "{{ username }}"
account_disabled: falseFAQ
What's the difference between locked and expired?
- Locked (
usermod -L): Password is prepended with!, can't authenticate - Expired (
expires: 0): Account expired, login denied regardless of password - Both can be active simultaneously — remove both to fully enable
How do I check expiry date?
- command: "chage -l {{ username }}"
register: chage_outputDoes enabling reset the password?
No — the original password is restored when unlocking. The ! prefix is simply removed.
Enable (Unlock) User
- name: Unlock user account
ansible.builtin.user:
name: john
password_lock: false
become: trueRe-enable Disabled Account
- name: Full re-enablement
ansible.builtin.user:
name: john
password_lock: false
shell: /bin/bash
expires: -1 # Remove expiry
become: trueSet Password and Enable
- name: Enable with new password
ansible.builtin.user:
name: john
password: "{{ 'NewPassword123' | password_hash('sha512') }}"
password_lock: false
update_password: always
become: true
no_log: trueBulk Enable Users
- name: Enable all team accounts
ansible.builtin.user:
name: "{{ item }}"
password_lock: false
shell: /bin/bash
expires: -1
loop:
- alice
- bob
- charlie
become: trueCheck Account Status
- name: Check if locked
command: passwd -S {{ username }}
register: account_status
changed_when: false
- debug:
msg: "{{ username }} is {{ 'locked' if 'L' in account_status.stdout.split()[1] else 'active' }}"
# Full status
- command: chage -l {{ username }}
register: account_info
changed_when: false
- debug: var=account_info.stdout_linesEnable/Disable Pattern
# Disable (offboarding)
- user:
name: "{{ departing_user }}"
password_lock: true
shell: /sbin/nologin
expires: 0
become: true
# Enable (re-onboarding)
- user:
name: "{{ returning_user }}"
password_lock: false
shell: /bin/bash
expires: -1
become: trueEnable SSH Access
- name: Enable user account
user:
name: "{{ username }}"
password_lock: false
shell: /bin/bash
become: true
- name: Restore SSH key
authorized_key:
user: "{{ username }}"
key: "{{ user_ssh_pub_key }}"
state: present
become: true
- name: Restore sudo access
copy:
content: "{{ username }} ALL=(ALL) NOPASSWD: ALL\n"
dest: "/etc/sudoers.d/{{ username }}"
mode: '0440'
validate: 'visudo -cf %s'
become: trueWindows Enable
- ansible.windows.win_user:
name: john
account_disabled: false
password_expired: falseAccount State Reference
| Action | Parameters |
|---|---|
| Lock account | password_lock: true |
| Unlock account | password_lock: false |
| Disable login | shell: /sbin/nologin |
| Enable login | shell: /bin/bash |
| Expire account | expires: 0 |
| Unexpire account | expires: -1 |
| Force password change | password_expired: true (Linux: use chage) |
FAQ
Difference between lock and disable?
Locking (password_lock) prevents password authentication. Setting shell: /sbin/nologin prevents all login. Use both for full disable.
How do I check if a user is locked?
passwd -S username
# L = locked, P = password set, NP = no passwordCan I enable without resetting the password?
Yes — password_lock: false unlocks without changing the password.
Unlock User Account
- ansible.builtin.user:
name: alice
password_lock: false
become: trueSet Login Shell (Re-enable)
- user:
name: alice
shell: /bin/bash # Was /usr/sbin/nologin
become: trueRemove Account Expiry
- user:
name: alice
expires: -1 # Remove expiry
become: trueFull Account Re-Enable
- hosts: all
become: true
tasks:
- name: Unlock password
user:
name: alice
password_lock: false
- name: Set login shell
user:
name: alice
shell: /bin/bash
- name: Remove account expiry
user:
name: alice
expires: -1
- name: Verify account status
command: "passwd -S alice"
register: status
changed_when: false
- debug:
msg: "{{ status.stdout }}"Enable Multiple Users
- user:
name: "{{ item }}"
password_lock: false
shell: /bin/bash
expires: -1
loop:
- alice
- bob
- charlie
become: trueSet Temporary Password
- user:
name: alice
password: "{{ 'TempPass123!' | password_hash('sha512') }}"
password_lock: false
update_password: always
become: true
no_log: trueCheck Account Status
- command: "chage -l {{ username }}"
register: account_info
changed_when: false
become: true
- debug:
var: account_info.stdout_linesEnable vs Disable Comparison
| Action | Module Parameters |
|---|---|
| Disable | password_lock: true, shell: /usr/sbin/nologin, expires: 0 |
| Enable | password_lock: false, shell: /bin/bash, expires: -1 |
| Delete | state: absent, remove: true |
FAQ
password_lock vs expires?
password_lock prevents password authentication. expires sets account expiry date. Use both for complete lockout.
How to check if account is locked?
passwd -S username
# L = locked, P = password set, NP = no passwordCan I force password change on next login?
- command: "chage -d 0 {{ username }}"
become: trueRelated Articles
Category: troubleshooting
Watch the video: Ansible Enable User Account: Unlock & Activate Users Guide — Video Tutorial