如何报告检查模式下 Ansible 命令/shell 任务的更改?

如何报告检查模式下 Ansible 命令/shell 任务的更改?

在我的 Ansible 剧本中,我有以下内容:

- name: "A: Check to see if we need to run task B"
  [... implementation omitted, not relevant ...]
  register: task_a_result
  check_mode: no  # even run in check mode
  changed_when: no  # this only reads/checks stuff

- name: "B: Write x to file"
  shell: "echo {{ my_var|quote }} > /path/to/file"
  when: task_a_result.stdout_lines[0].startswith('ABCDEF')
  changed_when: yes  # when run, it always changes the state

我愿意不是想要在检查模式下运行 B (因此,不行check_mode: no),但我想报告如果在非检查模式下运行,它会发生变化。我想要这种行为,因为我不想在非检查模式下运行时出现意外。然而,尽管changed_when: yes我自己设置了条件,Ansible 仍然显示任务为跳过因此未变大部头书:

skipping: [myhost] => changed=false 
  msg: skipped, running in check mode

(以上处于检查模式,并在常规非检查模式下报告“已更改”。)

我发现这个错误报告似乎被误解了并且不恰当地关闭了:14950,但我无法再对此发表评论。

我是否忽略了一些基本的东西?其他模块通常会在 Ansible 中完全正常地报告“将会发生改变”状态,但对于 shell/命令来说这也有可能吗?

使用 Ansible 2.7.12 和 2.8.2 会产生相同的结果。

我希望避免命令本身中的恶意攻击,例如:

- name: "B: Write x to file"
  shell: "echo {{ my_var|quote }} {{ '>' if task_a_result.stdout_lines[0].startswith('ABCDEF') else '' }} /path/to/file"
  when: task_a_result.stdout_lines[0].startswith('ABCDEF')
  changed_when: yes

是的,我知道我可以使用复制/模板模块写入文件,但我似乎无法做到覆写文件,例如echo 1234 > /sys/module/zfs/parameters/zfs_arc_max,因为 copy/template 似乎会尝试替换文件,而设置内核参数则不会这样工作。不,这个内核模块参数不会通过 Linux 上的 sysctl 公开。

答案1

我知道这有点过时了,但我正在寻找这个问题的解决方案。我也厌倦了命令模块作为 OP 带来的惊喜。

如果我们改变“命令”部分,使其在检查模式下执行不同的命令,结果会怎样?而且我们始终运行任务,即使在检查模式下也是如此。

注意:在您抱怨之前,我知道这是一个不好的例子。我知道“命令”模块中有一个“创建”选项。这只是举个例子。

这是我目前的解决方案:

- name: Get some info
  stat: {path: /tmp/somefile}
  register: file_info

- name: Run the command conditionally
  command:
    "{{ 'true' if (file_info['stat']['exists'] or ansible_check_mode)
    else 'touch /tmp/somefile' }}"
  changed_when: not file_info['stat']['exists']
  check_mode: false

它可以工作,但是很臃肿。

如果有更好的解决方案,请告诉我。

答案2

我也有类似的需求。我想看看命令是否会运行,这样当不在检查模式下运行时就不会出现意外。

作为一种解决方法,我添加了一个调试任务报告将会发生更改,并使用命令任务中的 when 条件在调试任务上设置changed_when,即

- name: "Report pending change"
  debug:
    msg: "Change pending"
  changed_when: task_a_result.stdout_lines[0].startswith('ABCDEF')
  when: ansible_check_mode|bool

相关内容