AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

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 AdministrationAnsible Vault Deep DiveAnsible become Privilege Escalation

Category: troubleshooting

Browse all Ansible tutorials · AnsiblePilot Home