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?
I'm going to show you a live Playbook with some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.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"This module has many parameters to perform any task.
The only required is "name", which is the username.
The parameter "state" allows us to create or delete a user.
The "password_lock" parameter specifies to unlock the user password if locked.
This parameter uses the 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: true
Remove account expiry
- name: Remove expiry date
ansible.builtin.user:
name: "{{ username }}"
expires: -1
become: true
Full 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: true
See 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: true
Check 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: false
FAQ
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_output
Does 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: true
Re-enable Disabled Account
- name: Full re-enablement
ansible.builtin.user:
name: john
password_lock: false
shell: /bin/bash
expires: -1 # Remove expiry
become: true
Set 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: true
Bulk 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: true
Check 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_lines
Enable/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: true
Enable 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: true
Windows Enable
- ansible.windows.win_user:
name: john
account_disabled: false
password_expired: false
Account 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 password
Can 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: true
Set Login Shell (Re-enable)
- user:
name: alice
shell: /bin/bash # Was /usr/sbin/nologin
become: true
Remove Account Expiry
- user:
name: alice
expires: -1 # Remove expiry
become: true
Full 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: true
Set Temporary Password
- user:
name: alice
password: "{{ 'TempPass123!' | password_hash('sha512') }}"
password_lock: false
update_password: always
become: true
no_log: true
Check Account Status
- command: "chage -l {{ username }}"
register: account_info
changed_when: false
become: true
- debug:
var: account_info.stdout_lines
Enable 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 password
Can I force password change on next login?
- command: "chage -d 0 {{ username }}"
become: true
Related Articles
• sudo and become in Ansible playbooks • Ansible inventory file structure • the Ansible roles overview • Ansible Windows administration walkthroughCategory: troubleshooting
Watch the video: Ansible Enable User Account: Unlock & Activate Users Guide — Video Tutorial