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: Change User Password with Ansible (Secure Guide)

By Luca Berton · Published 2024-01-01 · Category: installation

How to change user passwords with Ansible user module. Hash passwords securely, use Vault for credentials, manage password rotation across servers.

ansible.builtin.user: Change User Password with Ansible (Secure Guide)

Introduction

In today's episode of Ansible Pilot, I'm Luca Berton, and we'll be delving into the process of changing a user password on a Linux system using Ansible. Specifically, we'll be utilizing the ansible.builtin.user module, an integral part of Ansible's collection of built-in modules.

See also: Ansible Change User Password: Secure Password Management Guide

The Ansible User Module

The ansible.builtin.user module is a stable and well-established component of Ansible, designed to manage user accounts. It boasts compatibility with a wide range of Linux distributions, including RHEL, CentOS, Fedora, Ubuntu, Debian, SUSE, as well as SunOS, macOS, and FreeBSD. For Windows systems, the equivalent module is ansible.windows.win_user.

Parameters

The user module comes with various parameters, but the three key ones for our password-changing task are: • name (string): Specifies the username. • state (string): Indicates the desired state of the user account (present or absent). • password (string): For Linux systems, the password must be provided in encrypted form, while macOS accepts cleartext passwords.

Writing the Ansible Playbook

Let's take a practical approach by crafting an Ansible Playbook that changes the password for a user account on a Linux system.

Ansible Playbook Code: change_password.yml

---
- name: user module Playbook
  hosts: all
  become: true
  vars:
    myuser: "example"
    mypassword: "password"
  tasks:
    - name: change password
      ansible.builtin.user:
        name: "{{ myuser }}"
        state: present
        password: "{{ mypassword | password_hash('sha512') }}"

Executing the Playbook

To execute the playbook, use the following command:

$ ansible-playbook -i Playbook/inventory change\ user\ password/user.yaml

output

$ ansible-playbook -i Playbook/inventory change\ user\ password/user.yaml
PLAY [user module Playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [change password] ****************************************************************************
changed: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Verification

You can verify the password change by attempting to SSH into the system with the updated credentials:

$ sshpass -p 'password' example@demo.example.com

Note: Ensure that sshpass is installed on the system for this verification step.

See also: Add Secondary Groups to Linux Users with Ansible Playbook

Conclusion

In conclusion, you now possess the knowledge to change a user password on a Linux system using Ansible. The ansible.builtin.user module simplifies this task, allowing for seamless automation of user account management.

Set User Password

Ansible requires hashed passwords (not plaintext):

- name: Set user password
  ansible.builtin.user:
    name: deploy
    password: "{{ 'MySecureP@ss' | password_hash('sha512') }}"
  become: true

See also: Ansible Linux Users and Groups: Complete Management Guide (Examples)

Generate Password Hash

In playbook (using filter)

password: "{{ 'plaintext_password' | password_hash('sha512') }}"

With salt for consistency

password: "{{ 'plaintext_password' | password_hash('sha512', 'fixed_salt_value') }}"

From command line

ansible all -m debug -a "msg={{ 'MyPassword' | password_hash('sha512') }}"

# Or using Python python3 -c "import crypt; print(crypt.crypt('MyPassword', crypt.mksalt(crypt.METHOD_SHA512)))"

Secure Password Management

Use Ansible Vault

# vars/secrets.yml (encrypted with ansible-vault)
user_passwords:
  alice: "SecureP@ss123"
  bob: "AnotherP@ss456"
- name: Set passwords from vault
  ansible.builtin.user:
    name: "{{ item.key }}"
    password: "{{ item.value | password_hash('sha512') }}"
    update_password: always
  loop: "{{ user_passwords | dict2items }}"
  no_log: true  # Don't log passwords
  become: true

update_password options

| Value | Behavior | |-------|----------| | always | Update password every run | | on_create | Only set on new user creation |

# Only set password when creating user
- ansible.builtin.user:
    name: newuser
    password: "{{ password | password_hash('sha512') }}"
    update_password: on_create
  become: true

Force Password Change on First Login

- name: Create user with password
  ansible.builtin.user:
    name: newuser
    password: "{{ temp_password | password_hash('sha512') }}"
  become: true

- name: Force password change on next login ansible.builtin.command: chage -d 0 newuser become: true

Set Password Expiry

- name: Set password to expire in 90 days
  ansible.builtin.user:
    name: deploy
    password_expire_max: 90
  become: true

Windows Passwords

- name: Set Windows user password
  ansible.windows.win_user:
    name: admin_user
    password: "{{ vault_win_password }}"
    password_never_expires: true
    update_password: always

FAQ

Why can't I use plaintext passwords?

Linux stores hashed passwords in /etc/shadow. The user module writes directly to this file, so it needs the hash format. Plaintext would be stored as-is and never match during login.

Why does the task show "changed" every time?

If you generate the hash without a fixed salt, it's different each run. Use a fixed salt:

password: "{{ 'pass' | password_hash('sha512', 'mysalt') }}"

How do I check a user's current password?

You can't retrieve passwords. You can only check when it was last changed:

chage -l username

Set Password

- name: Set user password
  ansible.builtin.user:
    name: deploy
    password: "{{ 'MySecurePassword' | password_hash('sha512') }}"
    update_password: always
  become: true
  no_log: true

Password from Vault

# group_vars/all/vault.yml (encrypted)
vault_deploy_password: "SuperSecret123"

# playbook.yml - user: name: deploy password: "{{ vault_deploy_password | password_hash('sha512') }}" become: true no_log: true

Set on First Run Only

- user:
    name: newuser
    password: "{{ initial_password | password_hash('sha512') }}"
    update_password: on_create  # Only set if user is new
  become: true
  no_log: true

Force Password Change at Next Login

- user:
    name: deploy
    password: "{{ temp_password | password_hash('sha512') }}"
  become: true
  no_log: true

- command: chage -d 0 deploy become: true

Set Password Expiry

- user:
    name: deploy
    password: "{{ password | password_hash('sha512') }}"
    password_expire_max: 90   # Days until password expires
    password_expire_min: 7    # Min days between changes
  become: true
  no_log: true

Bulk Password Reset

- name: Reset all user passwords
  ansible.builtin.user:
    name: "{{ item.name }}"
    password: "{{ item.password | password_hash('sha512') }}"
    update_password: always
  loop:
    - { name: alice, password: "{{ vault_alice_pass }}" }
    - { name: bob, password: "{{ vault_bob_pass }}" }
    - { name: charlie, password: "{{ vault_charlie_pass }}" }
  become: true
  no_log: true

Generate Random Password

- set_fact:
    random_password: "{{ lookup('password', '/dev/null length=16 chars=ascii_letters,digits,punctuation') }}"

- user: name: newuser password: "{{ random_password | password_hash('sha512') }}" become: true no_log: true

- debug: msg: "Password for newuser: {{ random_password }}" # Only show during initial setup!

Password Hash Algorithms

# SHA-512 (recommended for Linux)
password: "{{ pass | password_hash('sha512') }}"

# SHA-256 password: "{{ pass | password_hash('sha256') }}"

# With custom salt password: "{{ pass | password_hash('sha512', 'mysalt') }}"

Windows Password

- ansible.windows.win_user:
    name: Administrator
    password: "{{ vault_admin_password }}"
    update_password: always

Security Best Practices

| Practice | Implementation | |----------|---------------| | Never hardcode passwords | Use ansible-vault | | Hide from logs | Add no_log: true | | Hash passwords | Always use password_hash() | | Rotate regularly | Set password_expire_max | | Use keys instead | authorized_key module |

FAQ

Why no_log: true?

Without it, the hashed password appears in Ansible output and logs. Always use no_log: true for password tasks.

"password not changed" but I set update_password?

update_password: on_create only sets passwords for new users. Use update_password: always to force updates.

Can I check the current password?

Ansible can't read existing passwords (they're hashed). You can only set new ones.

Set Password

- ansible.builtin.user:
    name: alice
    password: "{{ 'MySecurePass123!' | password_hash('sha512') }}"
    update_password: always
  become: true
  no_log: true

Password from Vault

# group_vars/all/vault.yml (encrypted)
vault_user_password: "SecurePassword123!"

# playbook - user: name: alice password: "{{ vault_user_password | password_hash('sha512') }}" become: true no_log: true

Update Only on Creation

- user:
    name: newuser
    password: "{{ initial_password | password_hash('sha512') }}"
    update_password: on_create  # Only set if user doesn't exist
  become: true
  no_log: true

Bulk Password Change

- user:
    name: "{{ item.name }}"
    password: "{{ item.password | password_hash('sha512') }}"
    update_password: always
  loop: "{{ users }}"
  become: true
  no_log: true
  vars:
    users:
      - { name: alice, password: "{{ vault_alice_pass }}" }
      - { name: bob, password: "{{ vault_bob_pass }}" }

Force Password Change on Next Login

- user:
    name: alice
    password: "{{ temp_password | password_hash('sha512') }}"
  become: true
  no_log: true

- command: "chage -d 0 alice" become: true

Generate Random Password

- set_fact:
    random_pass: "{{ lookup('password', '/dev/null length=16 chars=ascii_letters,digits,punctuation') }}"
  no_log: true

- user: name: alice password: "{{ random_pass | password_hash('sha512') }}" become: true no_log: true

- debug: msg: "Password for alice has been set" # Don't print the actual password!

Password Hashing Algorithms

# SHA-512 (recommended)
"{{ password | password_hash('sha512') }}"

# SHA-256 "{{ password | password_hash('sha256') }}"

# With custom salt "{{ password | password_hash('sha512', 'mysalt') }}"

# bcrypt (if supported) "{{ password | password_hash('blowfish') }}"

FAQ

Why no_log: true?

Without it, Ansible prints the hashed password in output logs. no_log prevents sensitive data from appearing in console output and logs.

Why not plain text passwords?

Ansible requires pre-hashed passwords. The password_hash filter handles hashing. Never store or transmit plain text passwords.

How to verify the password was set?

sudo chage -l username  # Shows password age info

Related Articles

become_user and become_method in AnsibleAnsible Inventory Guiderole variables and defaults in AnsibleWindows DSC and Ansible

Category: installation

Watch the video: ansible.builtin.user: Change User Password with Ansible (Secure Guide) — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home