在我的 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