balises Ansible peut être utilisé pour exécuter uniquement un sous-ensemble de tâches/rôles. Cela signifie que par défaut, toutes les tâches sont exécutées et nous ne pouvons empêcher que certaines tâches de s'exécuter.
Pouvons-nous limiter une tâche à exécuter uniquement lorsque la balise "foo" est spécifiée? Pouvons-nous utiliser les balises actuelles dans la section when
d'une tâche?
Ansible 2.5 est fourni avec des balises spéciales never
et always
. La balise never
peut être utilisée exactement à cette fin. Par exemple:
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
Dans cet exemple, la tâche ne s'exécutera que lorsque la balise debug
(ou never
) est explicitement demandée. [Référence sur les documents ansible]
Bien qu'il s'agisse d'une solution détournée, cela fonctionne.
Dans la liste des tâches, enregistrez une variable lors de l'exécution normale. Ensuite, ajoutez une condition when qui vérifie cette variable dans la tâche balisée.
- Shell: /bin/true
register: normal_task_list
- name: Only run when tag is specified
Shell: /bin/echo "Only running because of specified tag"
when: normal_task_list is not defined
tags: specified
Je n'ai pas assez de réputation pour voter ou commenter la réponse suggérant l'utilisation de variables de ligne de commande (--extra-vars
), mais je dois ajouter ceci:
La mise en garde à cette méthode est que le jeu va échouer et échouer si vous ne définissez pas cette variable supplémentaire.
Vous pouvez éviter l'échec de la lecture en l'absence d'un --extra-vars
définition en définissant une valeur par défaut dans le playbook lui-même:
---
- hosts: ...
# ↓↓↓
vars:
thorough: false
# ↑↑↑
tasks:
- name: apt - install nfs-common only when thorough is true
when: thorough | bool
apt:
cache_valid_time: 86400
force: yes
pkg:
- nfs-common
Remplacement via --extra-vars
fonctionnera toujours car les variables définies sur la ligne de commande ont priorité sur toutes les autres définitions.
Le résultat est que la lecture s'exécute sans erreur lorsque thorough
n'est pas remplacé par true
sur la ligne de commande.
Vous pouvez utiliser Conditions pour vous protéger contre l'exécution de tâches accidentelles qui seraient sinon exécutées si vous ne spécifiez pas de balise. La mise en garde à cette méthode est que le jeu va échouer et échouer si vous ne définissez pas cette variable supplémentaire.
En utilisant l'argument extra-vars, vous pouvez déclencher l'exécution de votre conditionnel.
De ansible-playbook --help:
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON
Exemple:
ansible-playbook test.yaml -e "thorough=true"
test.yaml:
...
- name: apt - install nfs-common only when thorough is true
apt:
cache_valid_time: 86400
force: yes
pkg:
- nfs-common
when: thorough | default(False)
...
La vérification de la variable 'tags' ne fonctionne pas dans Ansible 2.1.1.0. Voir ci-dessous pour le test. J'ai une autre idée pour exécuter la tâche uniquement lorsqu'une balise est définie, fonctionnant à la fois pour Ansible 1.9.X et 2.X.Y:
- set_fact: foo=true
tags: bar
- set_fact: foo=false
- name: do something when 'bar' tag is defined
debug: var=foo
when: foo
tags: bar
Avec cela, lors de l'exécution du playbook sans aucune balise, la variable 'foo' sera définie sur true puis sur false, donc rien n'est exécuté. Si vous ajoutez la balise 'bar', seul le premier paramètre sera appliqué, donc la variable 'foo' sera vraie, alors votre tâche sera exécutée. Prendre plaisir!
Et voici le test sur la variable 'tags' dans Ansible 2.1.1.0:
Voici le playbook:
- hosts: localhost
connection: local
tasks:
- name: display tags variable
debug: var=tags
tags: foo
- name: do something only when tag 'foo' is provided
debug: var=tag
when: tags is defined
tags: foo
Et voici la sortie:
$ ansible-playbook --version ; ansible-playbook ./test.yml -t foo
ansible-playbook 2.1.1.0
config file = /home/nootal/projects/ivy/src/ansible/ansible.cfg
configured module search path = Default w/o overrides
PLAY [localhost] ***************************************************************
TASK [display tags variable] ***************************************************
ok: [localhost] => {
"tags": "VARIABLE IS NOT DEFINED!"
}
TASK [do something only when tag 'foo' is provided] ****************************
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
Il existe une balise spéciale - "jamais" , qui empêchera l'exécution d'une tâche à moins qu'une balise ne soit spécifiquement demandée.
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
Oui. Exécuter ansible-playbook avec le --tags foo
flag garantira que seules les tâches marquées avec foo
seront exécutées. Par exemple, supposons que nous ayons un playbook appelé example.yml:
tasks:
- yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
tags:
- packages
- name: some other task
..
tags:
- some other tag
fonctionnement:
ansible-playbook example.yml --tags "packages"
S'assurera que seule la tâche yum est exécutée.
Donc, en réalité, vous n'avez pas vraiment besoin d'utiliser des balises dans la section when pour exécuter une tâche de manière conditionnelle. Notez qu'en fonction de la complexité de vos playbooks/rôles, vous devrez peut-être utiliser une combinaison de --tags et --skip-tags pour contrôler les tâches à exécuter. Par exemple, si une tâche d'inclusion est étiquetée comme 'foo' et qu'une tâche à l'intérieur du playbook inclus est étiquetée comme 'bar' et que vous exécutez
ansible-playbook --tags "foo"
La tâche interne (étiquetée uniquement comme "barre") sera exécutée. Pour éviter l'exécution de toutes les tâches internes marquées comme "bar", vous devrez exécuter la commande suivante
ansible-playbook --tags foo --skip-tags bar
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
C'est la bonne réponse, mais ce qui déroute souvent les gens, c'est comment obtenir Ansible pour ajouter cette balise, car si vous mettez --tags debug
sur la ligne de commande puis la seule chose qui s'exécute est les tâches de débogage. La solution est --tags all,debug
par exemple.
ansible-playbook play.yaml --tags all,debug
Le documents Ansible sur les balises a cette ligne:
Par défaut, Ansible s'exécute comme si --tags all avait été spécifié.
Sur Ansible 2.3.2.0
, voici ma solution au problème:
---
- hosts: localhost
gather_facts: no
vars:
in_tag: yes
tasks:
- set_fact: in_tag=no
- fail:
msg: "recently_added is set and you're using blah tag"
when: ( in_tag | bool )
tags:
- blah
- debug:
msg: "always remember"
Il commence par définir in_tag
à True
puis il y a set_fact
qui le redéfinit sur False
lorsque vous ne spécifiez pas tags
de ansible-playbook
.
Lorsque vous spécifiez des balises, in_tag
reste à True
et la tâche fail
s'exécute.
PS: vous pouvez ajouter la logique à toutes les tâches que vous souhaitez
PS2: vous pouvez également étendre la logique et coder en dur toutes les balises que vous avez et set_fact: in_tag_blah=True
en combinaison avec tags: ["blah"]
bien sûr.
when clause ne peut pas évaluer la présence de balises. Pour contourner ce problème, j'utilise des variables et des balises ensemble pour exécuter des tâches spécifiques à cette balise/variable.
Ex: Imaginez un livre de jeu et un inventaire
# inventaire [dev] 192.168.1.1 # site.yml - hôtes: dev rôles: - {rôle: commun} et dans commun/tâches/main.yml # rôles/commun/tâches/main.yaml - nom: installer les liens apt: nom = liens état = présent - inclure: uninstall.yml quand: uninstall_links est défini balises: - désinstaller # rôles/communs/tâches/uninstall.yml - nom: désinstaller les liens apt: nom = état des liens = absent
Avec cette approche, vous utilisez la balise pour sélectionner uniquement les tâches dans uninstall.yml, mais vous devez également définir la variable 'uninstall_links' sur quelque chose pour l'activer. Donc, si vous exécutez le playbook sans aucun paramètre, il exécutera par défaut la tâche d'installation. Pour désinstaller, vous pouvez définir le tag "désinstaller" sur votre playbook (ou cmdline) et [~ # ~] doit [~ # ~] définir le variable. Si vous ne définissez pas la balise, elle exécutera tout (installation et désinstallation) dans cet ordre, ce qui est bon pour tester l'ensemble du processus.
Comment tout exécuter (il va installer et désinstaller):
$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true"
Comment exécuter uniquement la balise 'uninstall' sur le groupe de développeurs
$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true" -t uninstall
Par conséquent, les variables et les balises peuvent également se trouver dans les fichiers site.yml/inventaire, vous permettant de vous engager dans votre SCM et d'enregistrer votre intention.
Une manière peut-être plus idiomatique et élégante consiste à ajouter une condition when
à la tâche, comme celle-ci:
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'debug' ]
when: "'debug' in ansible_run_tags"
Cela utilise la variable magique ansible_run_tags
qui contient la liste des balises fournies via l'argument CLI --tags
(ou synonyme -t
) et a pour effet d'exécuter la tâche ci-dessus si et seulement si la balise debug
est donnée.
Il semble que cette variable magique ait été introduite dans ansible 2.5
nootal a raison, mon approche ne fonctionne pas - ignorez-le :( J'utilise maintenant "quand: myvar est défini" et le commutateur de ligne de commande "-e" myvar = X "pour exécuter des tâches uniquement quand explicitement demandé.
Encore plus facile (au moins avec ansible 2.1.1.0):
- name: do something only when tag 'foo' is provided
when: tags is defined
tags: foo
-> ne s'exécutera que lorsque des balises auront été fournies ET les balises incluent "foo"