How can I stop ansible from writing passwords to the logfiles?
I am setting up a MySQL server and want Ansible to set the mysql-root
password during installation.
With the help of the internet I came up with this solution:
- name: Set MySQL root password before installing
debconf: name='mysql-server' question='mysql-server/root_password' value='{{mysql_root_pwd | quote}}' vtype='password'
- name: Confirm MySQL root password before installing
debconf: name='mysql-server' question='mysql-server/root_password_again' value='{{mysql_root_pwd | quote}}' vtype='password'
- name: Install Mysql
apt: pkg=mysql-server state=latest
mysql_root_pwd
is a variable loaded from the Ansible Vault. This runs fine, but now on the server there are many lines in the log:
Apr 10 14:39:59 servername ansible-debconf: Invoked with value=THEPASSWORD vtype=password question=mysql-server/root_password name=mysql-server unseen=None
Apr 10 14:39:59 servername ansible-debconf: Invoked with value=THEPASSWORD vtype=password question=mysql-server/root_password_again name=mysql-server unseen=None
How can I stop Ansible from writing clear text passwords to the logfiles?
Solution 1:
To prevent a task with confidential information from being logged, in syslog or other, set no_log: true
on the task:
- name: secret stuff
command: "echo {{secret_root_password}} | sudo su -"
no_log: true
The running of the task will still be logged, but with little details. Also, the module used has to support no_log
, so test custom modules.
See Ansible FAQ for further details. It can be applied to an entire playbook, however the output gets a little nasty with "censored!" messages.
Solution 2:
The observed behaviour seems to be a bug in the debconf module. I filed a bug report.
The user bcoca at github pointed out that one can use the no_log: true
directive in tasks, that set passwords, to prevent logging. This is a workaround, that works for me until the bug is fixed.
Solution 3:
There is a better way than just no_log: True
- name: write in string variables login and password
set_fact:
temp_user: "{{ USER_VAR }}"
temp_pass: "{{ PASSWORD_VAR }}"
- name: Your operation with password in output
shell: '/opt/hello.sh'
ignore_errors: True
no_log: True
register: myregister
- debug:
msg: '{{ myregister.stderr | regex_replace(temp_user) | regex_replace(temp_pass) }}'
when: myregister.stderr != ""
- debug:
msg: '{{ myregister.stdout | regex_replace(temp_user) | regex_replace(temp_pass) }}'
when: myregister.stdout != ""
- fail:
msg: "error shell /opt/hello.sh"
when: myregister.stderr != ""
As you can see, you need to add:
ignore_errors: true
no_log: true
And then make the output of the result of the command with regex_replace, where:
USER_VAR - login variable
PASSWORD_VAR - password variable
With this approach, you will not only hide the passwords and logins, but also get the output of your operation