Como faço para relatar uma tarefa de comando/shell do Ansible alterada no modo de verificação?

Como faço para relatar uma tarefa de comando/shell do Ansible alterada no modo de verificação?

No meu manual do Ansible, tenho o seguinte:

- 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

Eu façonãoquero executar B no modo de verificação (portanto, não check_mode: no), mas querorelatórioseria alterado se tivesse sido executado no modo sem verificação. Eu quero esse comportamento, porqueNão quero surpresas ao executar no modo sem verificação. No entanto, apesar de changed_when: yeseu mesmo ter definido uma condicional, o Ansible continua mostrando a tarefa comoignoradoe assiminalteradopara mim:

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

(O acima está no modo de verificação e relata 'alterado' no modo normal sem verificação.)

Encontrei este relatório de bug que parece mal interpretado e fechado de forma inadequada:14950, mas não posso mais comentar sobre isso.

Estou negligenciando algo básico? Outros módulos geralmente relatam um status "teria mudado" perfeitamente no Ansible, mas isso também é possível para shell/comando?

Usar o Ansible 2.7.12 e 2.8.2 produz os mesmos resultados.

Espero evitar hacks desagradáveis ​​no próprio comando, como:

- 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

E sim, eu sei que posso escrever em um arquivo com os módulos de cópia/modelo, mas não consigosubstituirarquivos com ele, por exemplo echo 1234 > /sys/module/zfs/parameters/zfs_arc_max, porque copy/template tentaria substituir o arquivo que parece e definir um parâmetro do kernel não funcionaria assim. E não, este parâmetro do módulo do kernel não é exposto através do sysctl no Linux.

Responder1

Eu sei que isso é meio antigo, mas estou procurando a solução para esse problema. Também estou cansado de surpresas com módulo de comando como OP.

E se alterarmos a parte do 'comando' para que ela execute um comando diferente no modo de verificação. E executamos a tarefa sempre, mesmo no modo de verificação.

Nota: Antes de reclamar, sei que este é um mau exemplo. Eu sei que existe uma opção 'cria' no módulo 'comando'. Isto é apenas para dar um exemplo.

Esta é a minha solução até agora:

- 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

Funciona, mas está inchado.

Por favor, diga-me se existem soluções melhores.

Responder2

Eu tenho uma necessidade semelhante. Gostaria de ver se o comando seria executado para não ter surpresas quando não for executado no modo de verificação.

Como solução alternativa, adicionei uma tarefa de depuração informando que haveria uma alteração e usei a condição quando da tarefa de comando para definir alterado_quando na tarefa de depuração, ou seja

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

informação relacionada