cron - Idempotencia y variables aleatorias en Ansible
(2)
En lugar de un valor aleatorio, podría obtener algo relacionado con el nodo, como un hash del nombre de host o el último byte de la dirección IP.
Esto es un ejemplo:
- name: Get a pseudo-random minute
shell: expr $((16#`echo "{{inventory_hostname}}" | md5sum | cut -c 1-4`)) % 30
register: minute
changed_when: false
¿Hay alguna manera de garantizar la idempotencia de los libros de jugadas que usan variables generadas aleatoriamente?
Por ejemplo, quiero configurar mis crontabs para desencadenar correos electrónicos en varios servidores en diferentes momentos, así que creo enteros aleatorios usando el módulo set_fact de ansible:
tasks:
- set_fact:
first_run_30="{{ 30 | random }}"
run_once: yes
Luego aplique esas variables generadas a mi crontab usando ansible así:
- name: Setup cron30job
cron: name=cron30job minute={{first_run_30}},{{first_run_30 | int + 30}} job=''/bin/bash /cron30job.sh'' state=present user=root
environment:
MAILTO: ''[email protected]''
MAILFROM: ''[email protected]''
Esto funciona muy bien, sin embargo, el principio de la indempotencia de ansible está, creo, roto con esta estrategia porque cada vez que se juega se ve un cambio:
TASK: [Setup cron30job] *****************************************
changed: [127.0.0.1]
Además, en la verificación de crontab en la raíz cada vez durante tres ejecuciones separadas:
[ansible]# cat /var/spool/cron/root
#Ansible: cron30job
5,35 * * * * /bin/bash /sw/test/cron30job.sh
#Ansible: cron30job
9,39 * * * * /bin/bash /sw/test/cron30job.sh
#Ansible: cron30job
6,36 * * * * /bin/bash /sw/test/cron30job.sh
Si hay una solución temporal, o tal vez la indefensión no será posible en mi escenario, me gustaría saber.
A partir de la versión 2.3 de Ansible, es posible inicializar el generador de números aleatorios a partir de una semilla. De esta forma, puedes crear números aleatorios pero idempotentes:
"{{ 59 |random(seed=inventory_hostname) }} * * * * root /script/from/cron"
Fuente: filtro de número aleatorio
He usado este patrón para producir tiempos de inicio cron aleatorios con:
- diferentes minutos en diferentes servidores de destino
- diferentes minutos para diferentes horas en el mismo servidor (aleatoriedad)
- el mismo minuto para el mismo día y el servidor cuando se ejecuta repetidamente Ansible (idempotencia)
Requiere Ansible> = 2.3:
cron:
name: "{{some_name}}_{{item.day}}"
state: present
job: "{{some_job}}"
weekday: "{{item.day}}"
hour: "{{item.hour}}"
minute: "{{59|random(seed=inventory_hostname + item.dow)}}"
with_items:
- { day: 0, hour: 3, dow: "sunday" }
- { day: 1, hour: 7, dow: "monday" }
- { day: 2, hour: 1, dow: "tuesday" }
- { day: 3, hour: 5, dow: "wednesday" }
- { day: 4, hour: 2, dow: "thursday" }
- { day: 5, hour: 4, dow: "friday" }
- { day: 6, hour: 7, dow: "saturday" }