ansible.builtin.user Module: Create & Manage Linux Users (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
Complete guide to ansible.builtin.user module. Create, delete, modify Linux user accounts, set passwords, SSH keys, groups, home directories.
The ansible.builtin.user module manages user accounts on Linux, macOS, and other Unix systems. It creates users, sets passwords, manages groups, SSH keys, home directories, shells, and account policies.
Create a User
- name: Create user
ansible.builtin.user:
name: deploy
comment: "Deployment user"
shell: /bin/bash
create_home: true
state: present
See also: Ansible Missing Sudo Password: Fix Passwordless SSH & Sudo Errors
Create User with Groups
- name: Create developer user
ansible.builtin.user:
name: alice
comment: "Alice Smith"
groups:
- docker
- sudo
append: true # Add to groups (don't replace existing)
shell: /bin/bash
⚠️ Always use append: true unless you want to REPLACE all secondary groups. Without it, the user is removed from any groups not listed.
Set Password
# Password must be hashed — NEVER use plaintext
- name: Create user with password
ansible.builtin.user:
name: bob
password: "{{ 'SecretPass123!' | password_hash('sha512', 'salt') }}"
update_password: on_create # Only set on creation, don't overwrite
# Generate password hash ahead of time
# python3 -c "from passlib.hash import sha512_crypt; print(sha512_crypt.hash('password'))"
| update_password | Behavior |
|-------------------|----------|
| always (default) | Reset password every run |
| on_create | Only set password when creating user |
See also: Add Secondary Groups to Linux Users with Ansible Playbook
Manage SSH Keys
# Generate SSH key pair
- name: Create user with SSH key
ansible.builtin.user:
name: deploy
generate_ssh_key: true
ssh_key_bits: 4096
ssh_key_comment: "deploy@{{ inventory_hostname }}"
# Add authorized key separately
- name: Add authorized SSH key
ansible.builtin.authorized_key:
user: deploy
key: "{{ lookup('file', 'keys/deploy_id_rsa.pub') }}"
state: present
Remove a User
# Remove user (keep home directory)
- name: Remove user
ansible.builtin.user:
name: olduser
state: absent
# Remove user AND home directory
- name: Remove user completely
ansible.builtin.user:
name: olduser
state: absent
remove: true # Deletes home dir and mail spool
See also: Ansible Linux Users and Groups: Complete Management Guide (Examples)
Lock / Unlock Account
# Lock account (disable login)
- name: Lock user account
ansible.builtin.user:
name: bob
password_lock: true
# Unlock account
- name: Unlock user account
ansible.builtin.user:
name: bob
password_lock: false
Set Account Expiry
# Account expires on specific date
- name: Create temp contractor account
ansible.builtin.user:
name: contractor
expires: 1735689600 # Unix timestamp (2025-01-01)
comment: "Temp contractor - expires Jan 2025"
# Never expire
- name: Remove expiry
ansible.builtin.user:
name: contractor
expires: -1
System User (No Login)
- name: Create service account
ansible.builtin.user:
name: appservice
system: true
shell: /usr/sbin/nologin
home: /opt/myapp
create_home: true
Key Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| name | — | Username (required) |
| state | present | present or absent |
| uid | — | User ID |
| group | — | Primary group |
| groups | — | Secondary groups (list) |
| append | false | Append to groups vs replace |
| shell | — | Login shell |
| home | — | Home directory path |
| create_home | true | Create home dir |
| password | — | Hashed password |
| update_password | always | always or on_create |
| system | false | Create system account |
| remove | false | Remove home on absent |
| generate_ssh_key | false | Generate SSH key pair |
| password_lock | — | Lock/unlock account |
| expires | — | Expiry (Unix timestamp) |
Practical Examples
Create Multiple Users from Variable
vars:
team_members:
- name: alice
groups: ['docker', 'sudo']
key: keys/alice.pub
- name: bob
groups: ['docker']
key: keys/bob.pub
- name: carol
groups: ['docker', 'sudo']
key: keys/carol.pub
tasks:
- name: Create team users
ansible.builtin.user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
append: true
shell: /bin/bash
loop: "{{ team_members }}"
- name: Add SSH keys
ansible.builtin.authorized_key:
user: "{{ item.name }}"
key: "{{ lookup('file', item.key) }}"
loop: "{{ team_members }}"
Setup Sudo Access
- name: Create admin user
ansible.builtin.user:
name: admin
groups: ['wheel'] # sudo group on RHEL
append: true
- name: Allow passwordless sudo
ansible.builtin.copy:
content: "admin ALL=(ALL) NOPASSWD:ALL\n"
dest: /etc/sudoers.d/admin
mode: '0440'
validate: visudo -cf %s
Deactivate Departed Employees
vars:
departed_users:
- john
- jane
tasks:
- name: Lock departed user accounts
ansible.builtin.user:
name: "{{ item }}"
password_lock: true
shell: /usr/sbin/nologin
expires: 0
loop: "{{ departed_users }}"
- name: Remove SSH keys
ansible.builtin.file:
path: "/home/{{ item }}/.ssh/authorized_keys"
state: absent
loop: "{{ departed_users }}"
Create User with Specific UID/GID
- name: Create group first
ansible.builtin.group:
name: appgroup
gid: 1500
- name: Create user with matching IDs
ansible.builtin.user:
name: appuser
uid: 1500
group: appgroup
home: /opt/app
user vs group Module
# Create group
- ansible.builtin.group:
name: developers
gid: 2000
state: present
# Then create users in that group
- ansible.builtin.user:
name: alice
group: developers
groups: ['docker']
append: true
FAQ
How do I set a password without it changing every run?
Use update_password: on_create:
password: "{{ 'mypass' | password_hash('sha512') }}"
update_password: on_create
This only sets the password when the user is first created.
How do I create a user that can't log in?
Set shell: /usr/sbin/nologin or shell: /bin/false. For service accounts, also set system: true.
Why does "append: false" remove my user from groups?
Without append: true, the groups parameter is the COMPLETE list of secondary groups. The user is removed from any group not listed. Always use append: true unless you intentionally want to replace group membership.
How do I check if a user exists?
Use getent:
- ansible.builtin.command: getent passwd bob
register: user_check
failed_when: false
changed_when: false
- ansible.builtin.debug:
msg: "User exists"
when: user_check.rc == 0
Conclusion
The user module handles all user lifecycle operations. Always hash passwords (never plaintext), use append: true for group management, and update_password: on_create for initial password setup. Pair with authorized_key for SSH key management and group for group creation.
Related Articles
• Ansible for Linux System Administration • Ansible Vault Deep Dive • Ansible become Privilege EscalationCategory: troubleshooting