2015-10-27 10 views
5

Gibt es eine Möglichkeit, Idempotenz für Playbooks zu garantieren, die zufällig generierte Variablen verwenden?Idempotenz und zufällige Variablen in Ansible

Zum Beispiel, ich möchte meine crontabs einrichten E-Mails auf mehreren Servern zu unterschiedlichen Zeiten auszulösen, so dass ich schaffen Zufallszahlen ansible des set_fact Modul:

tasks: 
    - set_fact: 
     first_run_30="{{ 30 | random }}" 
    run_once: yes 

Dann diese generierten Variablen auf meine crontab gelten mit ansible etwa so:

- 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]' 

Das funktioniert sehr gut, aber ansible der indempotence Prinzip ist, glaube ich, gebrochen mit dieser Strategie, weil jedes Mal, wenn eine Wiedergabe durchgeführt wird Sie eine Änderung sehen:

TASK: [Setup cron30job] ***************************************** 
changed: [127.0.0.1] 

Ferner wird in der crontab unter root Überprüfung jedes Mal während der drei Läufe:

[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 

Wenn es eine Abhilfe ist, oder vielleicht indempotence einfach nicht möglich sein, in meinem Fall würde Ich mag an kennt.

Antwort

6

Anstelle eines zufälligen Werts könnten Sie etwas erhalten, das sich auf den Knoten bezieht, z. B. einen Hash des Hostnamens oder das letzte Byte der IP-Adresse.

Dies ist ein Beispiel:

- name: Get a pseudo-random minute 
    shell: expr $((16#`echo "{{inventory_hostname}}" | md5sum | cut -c 1-4`)) % 30 
    register: minute 
    changed_when: false 
+0

Auch wenn dies der einzige Vorschlag ist, wie es scheint, die vernünftigste Lösung. Ich muss jedoch darauf hinweisen, dass die Aufgabe "Eine pseudozufällige Minute erhalten" den Status "[geändert]" meldet. Ich empfehle, 'changed_when: false' hinzuzufügen, um dies zu verhindern. Es zu umgehen, ist in diesem Fall in Ordnung, weil wir eine Auszahlung für die Crontab garantieren und wir wissen, dass der Hash-Wert sich nicht für jede Maschine ändert, es sei denn, Sie ändern den Hostnamen für diese IP (was eine Frage der eigenen Sache ist). – Jake88

+0

@ Jake88 guter Punkt! –

+0

Das ist großartig, aber ich hatte zwei Probleme. Erstens funktionierte expr nicht mit der Standard-Shell (/ bin/sh) auf debian, was meiner Meinung nach Bindestrich ist. Das Hinzufügen von 'args: executable:/bin/bash' half dabei. Zweitens hat expr einen Exit-Code von 1, wenn der Output 0 ist. 'Failed_when:" minute.rc == 2 or minute.rc == 3' behebt das, indem Exit-Code 1 nicht fehlschlägt. – Berdir

6

Ab ansible Version 2.3 ist es möglich, den Zufallszahlengenerator aus einem Samen zu initialisieren. Auf diese Weise können Sie Random-but-idempotent Zahlen erstellen:

"{{ 59 |random(seed=inventory_hostname) }} * * * * root /script/from/cron" 

Quelle: random number filter

ich dieses Muster verwendet habe zufällig cron mal beginnen mit zu produzieren:

  1. verschiedenen Minuten auf verschiedene Zielserver
  2. unterschiedliche Minuten für verschiedene Stunden auf dem gleichen Server (Zufälligkeit)
  3. die gleiche Minute für den gleichen Tag und Server, wenn sie wiederholt ansible läuft (idempotence)

Benötigt 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" } 
Verwandte Themen