How to NOT print items in an Ansible loop error without no_log
Solution 1:
There is a way to achieve desired behavior in multuple tasks with ansible's error handling. You can register
output of no_log
task and print only non-secret part in subsequent debug
:
- hosts: localhost
connection: local
tasks:
- block:
- shell: "/bin/false"
loop:
- name: "item1"
some_value: "my value"
secret: "p4$$w0rd"
- name: "item2"
some_value: "my value"
secret: "p4$$w0rd"
loop_control:
label: "{{ item.name }}"
# Capture tasks output
register: my_task
no_log: true
# Run this if task above fails
rescue:
# Print msg, stderr or whatever needed
- debug:
msg: "{{ item }}"
loop: "{{ my_task | json_query('results[*].msg') }}"
# finally fail a play
- fail:
In case if you need always print output (not only on task failure) use always
instead of rescue
and fail
task on condition:
- hosts: localhost
connection: local
tasks:
- block:
- shell: "/bin/true"
loop:
- name: "item1"
some_value: "my value"
secret: "p4$$w0rd"
- name: "item2"
some_value: "my value"
secret: "p4$$w0rd"
loop_control:
label: "{{ item.name }}"
register: my_task
no_log: true
always:
- debug:
msg: "{{ item }}"
loop: "{{ my_task | json_query('results[*].msg') }}"
- fail:
when: my_task['failed'] | default(false)
Update (2021-04-20)
As pointed by Lucas code above have number of downsides. Main idea was that output can be registered and filtered afterwards. Other parts of code are opinionated examples. There is certainly room for improvement. For example here is code that addresses issues 1, 4, 6, (and partially 2):
- hosts: localhost
connection: local
tasks:
- block:
- shell: "/bin/true"
register: my_task
no_log: true
# Register all loop-related keys so same loop settings can be reused in debug
<<: &loop
loop:
- name: "item1"
some_value: "my value"
secret: "p4$$w0rd"
- name: "item2"
some_value: "my value"
secret: "p4$$w0rd"
loop_control:
label: "{{ item.name }}"
index_var: index
always:
- debug:
# match result with item by index
msg: "{{ my_task['results'][index]['msg'] | default('ok') }}"
# reuse loop from main task
<<: *loop
- fail:
when: my_task['failed'] | default(false)
As for now it seems there is no way to implement desired behavior w/o workarounds. Ansible recommends writing logs to secure location in case it contains sensitive data.