Search code examples
ansiblepassword-hashansible-vault

Ansible Vault Passwords Exposed in Plain Text During Execution


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.


Solution

  • 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).