As I needed something similar, I created a test.yml playbook that hides things coming from a .secret file.
---
- hosts: localhost
vars:
hello_var: "{{ lookup('ini', 'hello_var type=properties file=config.secret') }}"
output_file: "/test.txt"
dirty_lines: ['cmd']
dirty_values: ['hello_env', 'hello_var']
dirty_word: "**SECRET**"
tasks:
- name: Write output file (has dirty content possibly, not showing output)
shell: "echo \"{{ hello_var }}\" > {{ output_file }}"
register: output_raw
ignore_errors: true
# don't forget
no_log: true
#- debug:
# var: output_raw
- name: Read secrets for 'Write output file'
shell: ansible-vault view --vault-password-file ./vault.secret ./config.secret
register: ansible_secret_content
# don't forget
no_log: true
- name: Filter passwords from the secrets for 'Write output file'
set_fact:
secrets: "{{ secrets|default([]) + [ item.split('=')[1] ] }}"
when: item.split('=')[0] in dirty_values
with_items: "{{ ansible_secret_content.stdout_lines | list }} "
# don't forget
no_log: true
#- debug:
# var: secrets
- name: Init cleaned output from 'Write output file'
set_fact:
output_cleaned: "{{ output_cleaned|default({}) | combine({item.key : item.value}) }}"
when: item.key not in dirty_lines
with_dict: "{{ output_raw }}"
# don't forget
no_log: true
#- debug:
# var: output_cleaned
- name: Init dirty output from 'Write output file'
set_fact:
output_dirty: "{{ output_dirty|default({}) | combine({item.key : item.value}) }}"
when: item.key in dirty_lines
with_dict: "{{ output_raw }}"
# don't forget
no_log: true
#- debug:
# var: output_dirty
- name: Clean the dirt for 'Write output file'
set_fact:
output_dirty: "{{ output_dirty|default({}) | combine({item[0] : output_dirty[item[0]].replace(item[1], dirty_word)}) }}"
loop: "{{ dirty_lines | product(secrets) | list }}"
# loops over the carthesian product of dirty_lines with dirty_values, providing a sort of nested loop
# don't forget
no_log: true
#- debug:
# var: output_dirty
- name: Combine output for 'Write output file'
set_fact:
output: "{{ output|default({}) | combine(output_cleaned) | combine(output_dirty) }}"
# don't forget
no_log: true
- name: Cleaned output for 'Write output file' (will show as failed if the original command failed also)
debug:
var: output
# Picking up the original error, if any
failed_when:
output.stderr != ''
#---
output:
PLAY [localhost] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Write output file (has dirty content possibly, not showing output)] ******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result", "changed": true}
...ignoring
TASK [Read secrets for 'Write output file'] ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
changed: [localhost]
TASK [Filter passwords from the secrets for 'Write output file'] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
ok: [localhost]
TASK [Init cleaned output from 'Write output file'] ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost]
TASK [Init dirty output from 'Write output file'] ******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
ok: [localhost]
TASK [Clean the dirt for 'Write output file'] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=None)
ok: [localhost] => (item=None)
ok: [localhost]
TASK [Combine output for 'Write output file'] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Cleaned output for 'Write output file' (will show as failed if the original command failed also)] ************************************************************************************************************************************************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {
"failed_when_result": true,
"output": {
"changed": true,
"cmd": "echo \"**SECRET**\" > /test.txt",
"delta": "0:00:00.001262",
"end": "2021-03-18 14:36:20.248332",
"failed": true,
"msg": "non-zero return code",
"rc": 2,
"start": "2021-03-18 14:36:20.247070",
"stderr": "/bin/sh: 1: cannot create /test.txt: Permission denied",
"stderr_lines": [
"/bin/sh: 1: cannot create /test.txt: Permission denied"
],
"stdout": "",
"stdout_lines": []
}
}
PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
localhost : ok=8 changed=2 unreachable=0 failed=1 skipped=0 rescued=0 ignored=1