当我使用一个循环执行 ansible 模块时,该模块包含包含模块要使用的值(包括机密信息)的字典,我可以使用 隐藏它loop_control.label
,但在发生错误时则不能。
- ansible.module:
arg1: "{{ item.name }}"
arg2: "{{ item.some_value }}"
arg3: "{{ item.secret }}"
arg4: "{{ item.throw_error }}"
loop:
- name: "item1"
some_value: "my value"
secret: "p4$$w0rd"
loop_control:
label: "{{ item.name }}"
Run Code Online (Sandbox Code Playgroud)
我可以使用 隐藏它no_log: true
,但它会隐藏所有内容,包括成功发生时以及错误消息,这可能完全没问题,并且当我看不到它时,让我对实际错误一无所知。
这类似于停止反向代理中的所有日志,或记录所有内容,包括授权标头,这两者在生产环境中都远远达不到预期。
那么,有没有办法让它在发生错误时不记录循环项,而是记录其他所有内容?它可以是一个任务标志,就像 一样no_log
,也可以是一些全局配置,包含在ansible.cfg
文件中。
更新(2021-04-19)
弗拉基米尔的答案实际上可以作为一种解决方法,但使用它有几个缺点:
jmespath
在运行过滤器之前安装该库json_query
。loop_control
with 。loop_var
label
任务中的循环debug
将与主循环任务中的循环不同(这可能会使将成功和错误情况与实际项目关联起来更加困难)。(而且可能还有更多缺点)
所以我最多能说的是,这是一种解决问题并创建其他问题的解决方法。
也就是说,我要求一个解决方案,并且根据 Ansible 目前的工作方式,提供的解决方法(或一些类似的解决方法)似乎是实现我要求的唯一方法。
我将权衡利弊,看看是否会实施此解决方法,或者是否继续按现在的方式使用它。
有一种方法可以通过ansible 的错误处理在多个任务中实现所需的行为。您可以register
输出no_log
任务并在后续中仅打印非秘密部分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:
Run Code Online (Sandbox Code Playgroud)
如果您需要始终打印输出(不仅在任务失败时),请使用always
代替rescue
和fail
任务条件:
- 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)
Run Code Online (Sandbox Code Playgroud)
更新(2021-04-20)
正如上面卢卡斯代码所指出的那样,它有很多缺点。主要思想是可以在之后注册和过滤输出。代码的其他部分是固执己见的示例。当然还有改进的空间。例如,下面是解决问题 1、4、6(以及部分问题 2)的代码:
- 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:
Run Code Online (Sandbox Code Playgroud)
就目前而言,似乎没有办法在没有解决方法的情况下实现所需的行为。Ansible建议将日志写入安全位置,以防其中包含敏感数据。