En mi libro de jugadas de Ansible tengo esto:
- 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
sínoQuiero ejecutar B en modo de verificación (por lo tanto, no check_mode: no
), pero quieroinformese modificó si se hubiera ejecutado en modo sin verificación. Quiero este comportamiento, porqueNo quiero sorpresas al ejecutar en modo sin verificación. Sin embargo, a pesar de tener changed_when: yes
y haber establecido un condicional, Ansible sigue mostrando la tarea comosaltadoy por lo tantosin alterara mi:
skipping: [myhost] => changed=false msg: skipped, running in check mode
(Lo anterior en modo de verificación e informa "cambiado" en modo normal sin verificación).
Encontré este informe de error que parece mal interpretado y cerrado de manera inapropiada:14950, pero ya no puedo comentar sobre eso.
¿Estoy pasando por alto algo básico? Otros módulos generalmente informan un estado "habría cambiado" perfectamente bien en Ansible, pero ¿esto también es posible para shell/comando?
El uso de Ansible 2.7.12 y 2.8.2 produce los mismos resultados.
Espero evitar hacks desagradables en el 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
Y sí, sé que puedo escribir en un archivo con los módulos de copia/plantilla, pero parece que no puedo.Sobrescribirarchivos con él, por ejemplo echo 1234 > /sys/module/zfs/parameters/zfs_arc_max
, porque parece que la copia/plantilla intentaría reemplazar el archivo y establecer un parámetro del kernel no funcionaría así. Y no, este parámetro del módulo del kernel no está expuesto a través de sysctl en Linux.
Respuesta1
Sé que esto es un poco antiguo, pero estoy buscando la solución a este problema. También estoy cansado de las sorpresas con el módulo de comando como OP.
¿Qué pasa si cambiamos la parte 'comando' para que ejecute un comando diferente en el modo de verificación? Y ejecutamos la tarea siempre, incluso en modo de verificación.
Nota: antes de que te quejes, sé que este es un mal ejemplo. Sé que hay una opción "crea" en el módulo "comando". Esto es sólo para dar un ejemplo.
Esta es mi solución hasta ahora:
- 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, pero está hinchado.
Por favor dígame si hay mejores soluciones.
Respuesta2
Tengo una necesidad similar. Me gustaría ver si el comando se ejecutaría para no tener sorpresas cuando no lo ejecute en modo de verificación.
Como solución alternativa, agregué una tarea de depuración que informaba que habría un cambio y usé la condición when de la tarea de comando para establecer el cambio_cuándo en la tarea de depuración, es decir
- name: "Report pending change"
debug:
msg: "Change pending"
changed_when: task_a_result.stdout_lines[0].startswith('ABCDEF')
when: ansible_check_mode|bool