Proper Password Handling in Ansible User Module: A Comprehensive Guide from Plain Text to Hash Encryption

Nov 21, 2025 · Programming · 14 views · 7.8

Keywords: Ansible | User Management | Password Encryption | SHA-512 | Playbook

Abstract: This article provides an in-depth exploration of correct password parameter usage in Ansible's user module, focusing on why using plain text passwords directly leads to authentication failures. It details best practices for generating SHA-512 encrypted passwords using the password_hash filter, with practical code examples demonstrating secure user password management. The discussion also covers password expiration strategies and idempotent playbook design, offering system administrators a complete Ansible user management solution.

Problem Background and Root Cause Analysis

When managing user accounts with Ansible, a common mistake is using plain text passwords directly in the password parameter of the user module. As shown in the original problem:

- name: Add deployment user
  action: user name=deployer password=mypassword

While this configuration executes successfully, user authentication always fails during login. The root cause lies in Linux systems storing password hashes rather than plain text, requiring Ansible to provide properly formatted encrypted passwords for writing to the system's /etc/shadow file.

Necessity of Password Hashing

Linux systems use one-way hash functions for password storage, meaning:

Ansible's user module requires the password parameter to be pre-computed encrypted hash values, which is crucial for correct password writing to the system shadow file.

Using password_hash Filter for Encrypted Passwords

Ansible provides the Jinja2 password_hash filter to dynamically generate encrypted passwords during playbook execution:

- name: Create user with encrypted password
  user:
    name: deployer
    password: "{{ 'mypassword' | password_hash('sha512') }}"
    groups: sudo
    append: yes

This approach offers several advantages:

Generating Hash Values with Python crypt Module

Another method involves using Python's crypt module to pre-generate encrypted passwords:

# Command to generate encrypted password
python -c 'import crypt; print(crypt.crypt("This is my Password", "$6$randomsalt$"))'

Then use in playbook:

- hosts: all
  vars:
    encrypted_password: $6$randomsalt$UqddPX3r4kH3UL5jq5/ZI.
  tasks:
    - name: Create user
      user:
        name: tset
        password: "{{ encrypted_password }}"

Note that Python's crypt module has been deprecated in newer versions, with passlib library recommended as replacement.

Password Expiration and Security Policies

To enhance security, it's recommended to set password expiration immediately after user creation:

- name: Create user account
  user:
    name: deployer
    password: "{{ deployer_password | password_hash('sha512') }}"
    shell: /bin/bash
    update_password: on_create
  register: user_created

- name: Force password change on first login
  shell: chage -d 0 deployer
  when: user_created.changed

This configuration ensures:

Security Best Practices

When managing sensitive passwords, follow these security guidelines:

Common Issues and Solutions

Issue 1: Receiving Python crypt module deprecation warnings

Solution: Install passlib library as replacement, or temporarily disable deprecation warnings in Ansible configuration.

Issue 2: Password hash incompatibility across different systems

Solution: Ensure all target systems use the same hash algorithm and salt generation method.

Conclusion

Proper usage of Ansible user module's password parameter requires understanding Linux password storage mechanisms and hash encryption principles. By employing the password_hash filter or pre-computed encrypted hash values, combined with password expiration strategies and security best practices, administrators can build secure and reliable user management automation workflows. This approach not only resolves password authentication failures but also enhances overall system security and maintainability.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.