web-dev-qa-db-fra.com

Ansible: plusieurs clauses an / ou conditionnelles dans la clause when

Je rencontre des problèmes lorsque j'essaie d'utiliser plusieurs conditions et/ou conditions dans une instruction when pour décider si une tâche doit être exécutée ou non. Fondamentalement, je fais un playbook pour effectuer des correctifs système automatisés avec des options pour les correctifs de sécurité, les correctifs du noyau uniquement et pour spécifier les packages dans un fichier var.

Je lance le playbook avec les commandes suivantes et définit les variables via l'option de variables étendues (-e)

ansible-playbook site.yml -i inventory --ask-vault -u (username) -e "security=true restart=true" -k -K

Par défaut, le playbook mettra à jour tous les packages du système, à l'exception du noyau, mais je voudrais ignorer cette action si je spécifie l'une des quelques variables. Le code que j'ai est le suivant:

- name: Update all packages
  yum:
     name: "*"
     state: latest
     exclude: "kernel*"
  when: security is not defined or kernel is not defined  or specified_packages 
 is not defined and ansible_os_family == "RedHat" 

Ive a essayé toutes les combinaisons suivantes:

when: (ansible_os_family == "RedHat") and (security is defined or kernel is defined or specified_packages is defined)

when: (ansible_os_family == "RedHat") and (security == true or kernel == true or specified_packages == true ) <- ce cas génère une erreur non définie car je ne définis pas toutes les variables à chaque fois que je lance le playbook

when: ansible_os_family == "RedHat" when: security is defined or kernel is defined or specified_packages is defined

Note: Je suis au courant et j'ai utilisé une variable supplémentaire telle que "skip" pour ignorer cette tâche et utiliser la clause when when: ansible_os_family == "RedHat" and skip is not defined Mais je préférerais que mes utilisateurs n'aient pas besoin d'utiliser un extra juste pour ignorer cette action par défaut.

Je n'utilise pas non plus de balises car je rassemble une liste de packages avant et après la mise à niveau pour comparer et rapporter à la fin, donc je ne pourrai pas les exécuter car ce sont des commandes d'action locale. C'est pourquoi j'utilise un rôle avec plusieurs tâches activées et désactivées via des variables étendues. Je suis ouvert à toute suggestion qui réécrit le playbook d'une manière plus efficace car je suis en quelque sorte un noob.

3
Jay

C'était une réponse si simple!

Les oeuvres suivantes:

when: not (security is defined or kernel is defined or specified_packages is defined) and ansible_os_family == "RedHat"
10
Jay

Comme @techraf l'a noté dans les commentaires, defined/undefined est un mauvais test ...

Refactoriser comme ceci:

when:
  - ansible_os_family == "RedHat"
  - security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != ''

Mettre à jour. Exemple reproductible:

- hosts: localhost
  gather_facts: no
  tasks:
    - debug:
        msg: hello
      when:
        - '"RedHat" == "RedHat"'
        - security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != ''

exécution:

ansible-playbook -e kernel=true playbook.yml

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "hello"
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

versions:

$ pip list | grep -iP 'ansible|jinja'
ansible (2.2.1.0)
Jinja2 (2.8)
3
Konstantin Suvorov