I am actually using Ansible to create user, with passwords stored in an Ansible Vault.
However, I've encountered an issue where the passwords, despite being in the Ansible Vault, are displayed in plain text in the console output during playbook execution.
The relevant section of my playbook looks like this:
- name: Create users
become: true
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
password: "{{ item.password | password_hash('sha512', 'salt') }}"
update_password: on_create
state: present
append: yes
shell: "{{ item.shell }}"
with_items: "{{ users }}"
When I run the playbook, it exposes passwords in plain text like this:
ok: [homeserver] => (item={'name': 'user1', 'groups': ['sambashare'], 'password': 'password', 'shell': '/sbin/nologin'})
ok: [homeserver] => (item={'name': 'user2', 'groups': ['sambashare'], 'password': 'azerty123', 'shell': '/sbin/nologin'})
I've tried the no_log: True
option, but it completely suppresses logging for the task, which isn't what I want. I've also tried nested variable references like "{{ '{{vaulted_password}}' | password_hash('sha512') }}"
, but they don't seem to work.
I want to keep logging enabled for debugging purposes, but I need to prevent the plain text passwords from appearing in the output. Ideally, I would like the output to show hashed versions of the passwords instead of the plain text.
Is there a way to keep my logs clean of sensitive data while still keeping the logging for other non-sensitive information?
I would appreciate any help or suggestions.
EDIT : It seems to be a limitation of ansible's user module that prevents me from managing my user list. I haven't found a real solution, but Zeitounator's answer may be a workaround.
The issue here is the output of the loop item. As a quick fix:
- name: Create users
become: true
ansible.builtin.user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
password: "{{ item.password | password_hash('sha512', 'salt') }}"
update_password: on_create
state: present
append: yes
shell: "{{ item.shell }}"
with_items: "{{ users }}"
loop_control:
label: "{{ item | combine({password: 'redacted'}) }}"
You can set label
to whatever best suit your need. See limiting loop output with label
Please note that the above is not bullet proof and that the original password might still be available while running your playbook in verbose mode (depending on the module... I believe that user
makes a rather good job on this one but you have to check...) and/or if you register the result of the looped task and output the result (where the orginal item
will be available for each result element).