如何報告 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 (因此, no 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,因為複製/模板會嘗試替換看起來的文件,並且設置內核參數不會像那樣工作。不,這個核心模組參數不會透過 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

相關內容