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: yes
eu 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