Comment faire en sorte qu'une vérification Ansible s'exécute une seule fois dans un playbook ?

StackOverflow https://stackoverflow.com//questions/22070232

  •  23-12-2019
  •  | 
  •  

Question

Pour éviter d'utiliser un playbook obsolète, j'aimerais m'assurer d'avoir une copie mise à jour de git checkout avant qu'Ansible ne soit autorisé à modifier quoi que ce soit sur les serveurs.

C'est ainsi que j'ai essayé de procéder.Cette action se trouve dans un fichier inclus dans tous les playbooks :

- name: Ensure local git repository is up-to-date
  local_action: git pull
  register: command_result
  failed_when: "'Updating' in command_result.stdout"

Le problème est que cette commande est exécutée une fois pour chaque nœud auquel Ansible se connecte, au lieu d'une seule fois pour chaque exécution du playbook.Comment puis-je éviter cela ?

Était-ce utile?

La solution

Mis à jour

Lorsque j'ai écrit ma première réponse (2014-02-27), Ansible n'avait pas de support intégré pour exécuter une tâche. juste une fois par playbook, pas une fois par hôte concerné sur lequel le playbook a été exécuté.Cependant, comme tlo écrit, la prise en charge de cela a été introduite avec run_once: true dans Ansible version 1.7.0 (publiée le 06/08/2014).Avec cette fonctionnalité, l'exemple de définition de tâche de la question doit être remplacé par

- name: Ensure local git repository is up-to-date
  local_action: git pull
  run_once: true
  register: command_result
  failed_when: "'Updating' in command_result.stdout"

pour accomplir ce qui est demandé.

Réponse originale

[La réponse suivante était ma solution suggérée pour le problème particulier consistant à s'assurer que la branche git locale est mise à jour avant qu'Ansible n'exécute les tâches d'un playbook.]

J'ai écrit le plugin de rappel Ansible suivant qui évitera l'exécution du playbook si la branche git actuelle est désynchronisée (est en retard ou a divergé) avec la branche distante.Pour l'utiliser, placez le code suivant dans un fichier comme callback_plugins/require_updated_git_branch.py dans votre répertoire de playbook Ansible de niveau supérieur :

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import os
import re
import subprocess
import sys

from ansible.callbacks import display, banner


class CallbackModule(object):
    """Makes Ansible require that the current git branch is up to date.
    """
    env_var_name = 'IGNORE_OUTDATED_GIT_BRANCH'

    msg = 'OUTDATED GIT BRANCH: Your git branch is out of sync with the ' \
          'remote branch.  Please update your branch (git pull) before ' \
          'continuing, or skip this test by setting the environment ' \
          'variable {0}=yes.'.format(env_var_name)

    out_of_sync_re = re.compile(r'Your branch (is behind|and .* have diverged)',
                                re.MULTILINE)

    def __init__(self, *args, **kwargs):
        if os.getenv(self.env_var_name, 'no') == 'yes':
            self.disabled = True

    def playbook_on_start(self):
        subprocess.call(['git', 'fetch'])

        if self.out_of_sync_re.search(subprocess.check_output([
            'git', 'status', '--untracked-files=no'])):
            display(banner(self.msg), color='bright purple')
            sys.exit(1)

Par exemple, lorsque la branche locale est derrière la branche distante, la commande ansible-playbook site.yml s'arrête plus tôt avec le résultat suivant :

 __________________________________________________________
/ OUTDATED GIT BRANCH: Your git branch is out of sync with \
| the remote branch. Please update your branch (git pull)  |
| before continuing, or skip this test by setting the      |
\ environment variable IGNORE_OUTDATED_GIT_BRANCH=yes.     /
 ----------------------------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Et, comme le suggère la vache, pour désactiver cette vérification, vous pouvez exécuter la commande suivante :

$ IGNORE_OUTDATED_GIT_BRANCH=yes ansible-playbook site.yml

Cette solution ne résout pas le problème général consistant à éviter d'exécuter une tâche Ansible plus d'une fois, quel que soit le nombre d'hôtes impliqués, mais elle garantit que les playbooks obsolètes ne sont pas exécutés et résout le problème que vous avez mentionné concernant mon suggestion basée sur un alias.

Autres conseils

Depuis la version 1.7 de Ansible, vous pouvez utiliser run_once: true pour exécuter une tâche uniqueet seulement sur un hôte .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top