Ansible: Comment exécuter un hôte de tâche par hôte?

15

Au niveau du jeu, nous devons serial: 1nous permettre d'exécuter le jeu entier un hôte à la fois. Mais je n'ai pas trouvé de moyen simple de le faire sur une seule tâche. Cela est particulièrement pertinent si la tâche en question n'effectue pas un verrouillage approprié (pour une raison quelconque).

Une réponse évidente est de mettre la tâche dans son propre jeu. Mais cela n'aide pas avec les rôles. (Devoir serial: 1jouer le jeu en utilisant le rôle n'est pas vraiment intuitif.)

Elrond
la source

Réponses:

11

Si vous ne voulez pas de parallélisme dans l'exécution des étapes de votre playbook, définissez le niveau de fork à 1:

ansible-playbook --forks=1 ...

Vous pouvez également le mettre dans votre fichier cfible ansible:

[defaults]
forks=1

mais si vous le souhaitez sur une base individuelle, utilisez l'option de ligne de commande ci-dessus.

ÉDITER:

serial: 1fait quelque chose de complètement différent: c'est comme exécuter le playbook pour chaque hôte tour à tour, attendre la fin du playbook complet avant de passer à l'hôte suivant. forks=1signifie exécuter la première tâche dans un jeu sur un hôte avant d'exécuter la même tâche sur l'hôte suivant, donc la première tâche sera exécutée pour chaque hôte avant que la tâche suivante ne soit touchée.

Vous ne voulez donc forks=1qu'une seule pièce; malheureusement ce n'est pas possible actuellement.

gémir
la source
2
Je ne cherchais pas à mettre cela sur un livre de jeu entier. C'est beaucoup à non granulaire. serial: 1laissez-moi le mettre sur une pièce au moins. Mais je veux seulement le placer sur un sous-élément d'une pièce (quel que soit le nom correct de cela. Je pensais que c'était "tâche", mais le commentaire ci-dessus semble être en désaccord).
Elrond
3
serial: 1fait quelque chose de complètement différent: c'est comme exécuter le playbook pour chaque hôte tour à tour, attendre la fin du playbook complet avant de passer à l'hôte suivant. forks=1signifie exécuter la première tâche dans un jeu sur un hôte avant d'exécuter la même tâche sur l'hôte suivant, donc la première tâche sera exécutée pour chaque hôte avant que la tâche suivante ne soit touchée. Vous ne voulez donc forks=1qu'une seule pièce; malheureusement ce n'est pas possible actuellement.
wurtel
Bon point! Pourriez-vous ajouter cela à la réponse?
Elrond
2

Il existe une solution de contournement à ce problème - on peut transmettre la liste des hôtes (ou un groupe) à with_items, puis l'utiliser delegate_toavec cette liste. De cette façon, la tâche sera exécutée hôte par hôte.

Par exemple:

- name: start and enable rabbitmq (run task host by host)
  service:
    name: "rabbitmq-server"
    state: "started"
    enabled: true
  delegate_to: "{{ item }}"
  with_items: "{{ groups['rabbitmq-cluster'] }}"
  run_once: true
Tomasz Klosinski
la source
Pour ceux qui se demandent pourquoi run_once: trueest là-dedans, essayez de le retirer. Vous n'aimerez pas ce qui se passe. (tant de pistes répétées aaaahhhh)
Almenon
1

Si vous l'exécutez sur une seule machine, un problème de verrous exclusifs se pose pour plusieurs hôtes. Vous devez donc exécuter un par un pour tous les hôtes. Pour cela, vous devez avoir --forks=1été défini lors de l'appel de la commande ansible playbook. Pour un exemple: ansible-playbook webserver.yml --forks=1où webserver.yml a app01 et app02 dans votre[webserver]

Rohan Seth
la source
0

Pensez à ce que vous voulez

run_once: true

user19151
la source
4
nope: "run_once: true" signifie d'exécuter la tâche pour exactement un hôte dans la liste des hôtes. Je veux l'exécuter pour chaque hôte de la liste, mais l'un après l'autre.
Elrond
0

Pour les commandes pouvant être exécutées localement, utilisez une boucle pour parcourir tous les hôtes de la lecture. Cela ne fonctionne que si la commande peut être exécutée localement. Vous pouvez également exécuter une commande contenant ssh sur les machines distantes une par une de cette manière, si les clés sont configurées, mais cela devient difficile lorsque vous parlez d'escalade.

PAR EXEMPLE:

- name: Init New Appliances - Remove the known hosts entry for the server in case it has changed
  run_once: yes
  connection: local
  become: no
  command: "ssh-keygen -R {{ item }}"
  with_items:
  - "{{ inventory_hostname }}"
Michele
la source
1
Vous devez fournir une liste d'hôtes au lieu de simplement sur l'hôte nommé inventory_hostname, sinon la boucle n'a aucun sens.
Konstantin Suvorov