19
0
Fork 0

Améliorations

This commit is contained in:
Gregory Colpart 2017-03-03 16:21:27 +01:00
parent 66984e0dac
commit 21485e74a4
1 changed files with 43 additions and 72 deletions

View File

@ -254,11 +254,12 @@ Pour avoir plus d'infos sur un module :
(…)
~~~
*Note* : c'est pratique pour avoir la documentation exacte pour votre version d'Ansible. En effet, celle du site corespond à la dernière version et n'indique pas toujours toutes les différences.
> *Note* : c'est pratique pour avoir la documentation exacte pour votre version d'Ansible. En effet, celle du site corespond à la dernière version et n'indique pas toujours toutes les différences.
### playbook
<http://docs.ansible.com/ansible/playbooks.html>
Un playbook va ensuite dérouler des _actions_ qui seront organisées en _tasks_, [roles](#roles) et [handlers](#handlers).
Exemple de playbook simple :
@ -311,7 +312,7 @@ Un playbook plus évolué :
# vim:ft=ansible:
~~~
On lance ainsi le playbook :
On lance des playbooks ainsi :
~~~
$ ansible-playbook PLAYBOOK.yml --limit HOSTNAME --forks 1
@ -355,17 +356,17 @@ $ ansible-playbook -l "*[0:9]" playbook.yml
$ ansible-playbook -l "*[10:]" playbook.yml
~~~
Il est de toute façon préférable de ne pas mettre `all` dans le champs `hosts` dans le playbook pour éviter un - _possible_ - oubli de "limite" de machines.
Il est de toute façon préférable de ne pas mettre `all` dans le champs `hosts` dans le playbook pour éviter un oubli.
### handlers
Les **handlers** ne sont exécutées que si une action a fait la demande, via la directive `notify` disponible pour tous les modules.
Les **handlers** sont des actions définies dans un playbook, qui ne sont exécutées que dans certains cas.
On utilise l'option `notify` au sein d'un module pour évoquer un handler. Celui-ci ne sera exécuté que si un module a effectivement provoqué un changement.
L'usage classique est de recharger un service après une modification de configuration : si la modification est réalisée => le service est rechargé, si la modification est déjà effectuée => aucune action.
L'enregistrement du handler se fait seulement lorsque l'action a provoqué un changement.
L'exécution effective du handler se fait **une seule fois** en fin de "play", quel que soit le nombre de fois où il a été demandé pendant l'exécution.
Par défaut, l'exécution effective des handlers se fait **une seule fois** à la fin du playbook, quel que soit le nombre de fois où il a été demandé pendant l'exécution.
Les handlers servent le plus souvent à redémarrer des services. Exemple :
Exemple :
~~~{.yaml}
tasks:
@ -388,6 +389,8 @@ Dans des rôles longs, nous conseillons de purger les handlers de temps en temps
### roles
<http://docs.ansible.com/ansible/playbooks_roles.html>
Lorsqu'on a besoin d'utiliser des fichiers ou _templates_ à copier, des variables avec des valeurs par défaut, des handlers… on peut organiser tout cela dans un **role** en respectant la structure conventionnelle suivante :
~~~
@ -410,6 +413,8 @@ foo
└── main.yml
~~~
À titre d'exemple, voici des rôles Ansible que nous utilisons : <https://forge.evolix.org/projects/ansible-roles/repository?rev=unstable>
### inventory
<http://docs.ansible.com/ansible/intro_inventory.html>
@ -447,8 +452,8 @@ proxy=proxy.mercerie.example.com
* `hostname.internal` : serveur présent dans aucun groupe
* `[httpservers]` : le nom du groupe (pour les serveurs http). Les noms de hosts qui suivent appartiendront à ce groupe
* `machine[01:57].evolix.net` : on peut indiquer une [pseudo-]expression régulière - ici ajoutera les machines _machine01.evolix.net_, _machine02.evolix.net_, _machine03.evolix.net_… _machine57.evolix.net_
* `http.evolix.net:2222` : ansible se connecte par ssh, et _http.evolix.net_ a un port SSH d'écoute différent qui est 2222
* `machine[01:57].example.com` : on peut indiquer une [pseudo-]expression régulière - ici ajoutera les machines _machine01.example.com_, _machine02.example.com_, _machine03.example.com_… _machine57.example.com_
* `HOSTNAME:2222` : ansible se connecte par ssh, et _HOSTNAME_ a un port SSH d'écoute différent qui est 2222
* `[dbservers]` : groupe pour les serveurs de base de données
* `machine50.example.com` : cette machine est déjà présente dans le groupe _httpservers_, mais sera aussi accessible à partir du groupe _dbservers_
* `alias ansible_port=2222 ansible_host=192.168.1.50` : la machine _alias_ n'a pas un vrai FQDN mais pointera vers _192.168.1.50_ car on a indiqué des variables propres à Ansible. Il est existe aussi `ansible_connection` (local ou ssh) ou `ansible_user` (le nom de l'utilisateur de la machine distante avec lequel Ansible se connectera en ssh)
@ -462,14 +467,13 @@ On peut aussi découper le fichier "inventory" selon les groupes et les variable
Les variables propres à Ansible : <http://docs.ansible.com/ansible/intro_inventory.html#list-of-behavioral-inventory-parameters>
### variables
Les variables sont un élément clé de la configuration des playbooks et roles. Exemple :
~~~{.yaml}
vars:
ip: 31.170.9.129
ip: 192.0.2.42
conf_file: /etc/foo.conf
tasks:
@ -534,7 +538,7 @@ On peut aussi n'éxecuter que certains tags :
$ ansible-playbook (…) --tags "configuration,packages"
~~~
Note : on peut également _taguer_ des rôles `include`.
> *Note* : on peut également _taguer_ des rôles `include`.
### Register
@ -572,7 +576,7 @@ La configuration est lue dans l'ordre suivant :
### ansible.cfg
Options utiles (TODO : à revoir) :
Quelques options qui peuvent être utiles :
* `display_args_to_stdout` : mettre à `True` si on veut voir tout le contenu du _tasks_ executé pour chaque étape écrit sur _stdout_
* `display_skipped_hosts` : mettre à `False` si on ne veut pas voir affiché sur _stdout_ l'information d'un _task_ qui n'est pas exécuté _(le nom de variable est confu - mais il s'agit bien de l'affichage du task)_
@ -591,63 +595,30 @@ Options utiles (TODO : à revoir) :
### unbalanced jinja2 block or quotes
~~~
fatal: [test.evolix.net]: FAILED! => {"failed": true, "reason": "error while splitting arguments, either an unbalanced jinja2 block or quotes"}
fatal: [HOSTNAME]: FAILED! => {"failed": true, "reason": "error while splitting arguments, either an unbalanced jinja2 block or quotes"}
~~~
Vérifier bien la syntaxe du document qui est référé pour cette erreur. Cela peut être un guillemet mal fermé (ou mélange simples/doubles guillemets), ou encore histoire de crochet devenant une parenthèse…
### UNREACHABLE!
~~~
fatal: [test.evolix.net]: UNREACHABLE! => {"changed": false, "msg": "SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue", "unreachable": true}
~~~
Malheureusement, cela arrive souvent sur certaines machines (une ?), mais pas de solution pour le moment -> boire du café - beaucoup de café.
Du côté de la machine distante, dans le fichier `/var/log/auth.log`:
~~~
14:56:29 localhost sshd[19915]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=dual.evolix.net user=service
14:56:31 localhost sshd[19915]: Accepted password for service from 192.168.4.137 port 42502 ssh2
14:56:31 localhost sshd[19915]: pam_unix(sshd:session): session opened for user service by (uid=0)
14:56:31 localhost systemd-logind[641]: New session 181 of user service.
14:56:32 localhost sshd[19915]: pam_unix(sshd:session): session closed for user service
14:56:32 localhost systemd-logind[641]: Removed session 181.
~~~
Et quand ça marche - la session ne se referme pas, et est réutilisé par les exécutions playbook suivantes:
~~~
14:58:57 localhost sshd[20339]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=dual.evolix.net user=service
14:59:00 localhost sshd[20339]: Accepted password for service from 192.168.4.137 port 42511 ssh2
14:59:00 localhost sshd[20339]: pam_unix(sshd:session): session opened for user service by (uid=0)
14:59:00 localhost systemd-logind[641]: New session 182 of user service.
(…)
15:01:08 localhost sshd[23034]: Received disconnect from 192.168.4.137: 11: disconnected by user
15:01:08 localhost sshd[23024]: pam_unix(sshd:session): session closed for user service
15:01:08 localhost systemd-logind[641]: Removed session 182.
~~~
Mais si tentative de déploiement Ansible juste après la session supprimée (par ex la 182), c'est à ce moment là qu'on se retrouve avec des *UNREACHABLE* -> savoir pourquoi sshd supprime la session ssh…
Bien vérifier la syntaxe : cela peut être un guillemet mal fermé (ou mélange simples/doubles guillemets), ou encore histoire de crochet devenant une parenthèse…
### Missing required arguments
~~~
fatal: [test.evolix.net]: FAILED! => {"changed": false, "failed": true, "msg": "missing required arguments: section"}
fatal: [HOSTNAME]: FAILED! => {"changed": false, "failed": true, "msg": "missing required arguments: section"}
~~~
Le message est assez clair, donc bien relire la doc du module sur Ansible, et toujours ajouter les arguments obligatoires pour ce module.
Le message est assez clair, donc bien relire la doc du module sur Ansible pour ajouter les arguments obligatoires pour ce module.
### Requires stdlib json or simplejson module
~~~
fatal: [lenny.evolix.net]: FAILED! => {"changed": false, "failed": true, "msg": "Error: ansible requires the stdlib json or simplejson module, neither was found!"}
fatal: [HOSTNAME]: FAILED! => {"changed": false, "failed": true, "msg": "Error: ansible requires the stdlib json or simplejson module, neither was found!"}
~~~
~~~
# apt install python-simplejson
~~~
## Astuces
### Vérifier un playbook
@ -658,15 +629,15 @@ fatal: [lenny.evolix.net]: FAILED! => {"changed": false, "failed": true, "msg":
$ ansible-playbook --syntax-check my-experimental-playbook.yml
~~~
<http://www.yamllint.com/>
Voir <http://www.yamllint.com/>
* vérifier les actions qui vont être faite s(mode `dry-run`) sans rien exécuter :
* vérifier les actions qui vont être faites (mode `dry-run`) sans rien exécuter :
~~~
$ ansible-playbook --check my-experimental-playbook.yml
~~~
*Note* : certaines actions ne sont pas exécutées en mode "check", cela peut donc perturber celles qui sont bassées dessus.
> *Note* : certaines actions ne sont pas exécutées en mode "check", cela peut donc perturber celles qui sont bassées dessus.
* avoir le diff des fichiers modifiés (ne marche pas avec les modules `replace`/`lineinfile` à priori) :
@ -714,7 +685,7 @@ Pour éviter que les différentes tâches s'appliquent une par une sur tout les
strategy: free
~~~
*Note*: ne plus se fier au texte `host changed` après texte de la tâche, car il pourrait s'agir d'une autre tâche affichée plus en haut dans le texte de l'historique.
> *Note*: ne plus se fier au texte `host changed` après texte de la tâche, car il pourrait s'agir d'une autre tâche affichée plus en haut dans le texte de l'historique.
### Fréquence des hosts
@ -725,6 +696,8 @@ Lors de l'exécution d'un play, on peut indiquer une fréquence sur le nombre d'
### Cowsay
<https://support.ansible.com/hc/en-us/articles/201957877-How-do-I-disable-cowsay->
Si la commande `cowsay` est disponible sur votre machine, vous verrez un message à la fin :
~~~
@ -750,22 +723,22 @@ Pour le désactiver : `export ANSIBLE_NOCOWS=1`
Disponible aussi dans la conf du fichier `/etc/ansible/ansible.cfg`
<https://support.ansible.com/hc/en-us/articles/201957877-How-do-I-disable-cowsay->
### Conditions dans fichier jinja2
<http://jinja.pocoo.org/docs/dev/templates/#builtin-tests>
~~~
{% if python_is_installed is defined %}
Ansible devrait marcher -pardi!
{% endif %}
~~~
<http://jinja.pocoo.org/docs/dev/templates/#builtin-tests>
Voir la doc pour plus de détails : <http://jinja.pocoo.org/docs/dev/>
### Lire une entrée au clavier
<https://docs.ansible.com/ansible/playbooks_prompts.html>
S'il manque une valeur pour la suite du script, soit on le gère en mettant une erreur, ou une valeur par défaut, mais sinon on peut aussi demander une saisie clavier :
~~~{.yaml}
@ -789,16 +762,14 @@ Si on veut utiliser cette variable dans une tâche, il faut simplement utiliser
prenom_de_autre: prenom
~~~
<https://docs.ansible.com/ansible/playbooks_prompts.html>
### Exécuter un playbook en mode interactif
<https://docs.ansible.com/ansible/playbooks_startnstep.html>
~~~
$ ansible-playbook playbook.yml --step
~~~
<https://docs.ansible.com/ansible/playbooks_startnstep.html>
### Ne pas lancer une commande shell si le fichier existe
En indiquant l'argument `creates` indiquant le chemin de fichier lors de l'utilisation du module shell, cette tâche ne s'exécutera que si le fichier indiqué par `creates` n'existe pas.
@ -808,7 +779,9 @@ Ces arguments sont disponibles pour certains modules (comme `shell`).
C'est beaucoup plus simple et rapide que de tester le fichier par le module `stat` juste avant.
### Lancer tâche sur machine précise (voire locale)
### Lancer tâche sur machine précise (voire localhost)
<https://docs.ansible.com/ansible/playbooks_delegation.html#delegation>
~~~
- name: /etc/hosts
@ -822,10 +795,10 @@ C'est beaucoup plus simple et rapide que de tester le fichier par le module `sta
Pour une exécution locale, on peut aussi utiliser l'attribut `local_action`.
<https://docs.ansible.com/ansible/playbooks_delegation.html#delegation>
### Ne lancer tâche qu'une seule fois
<https://docs.ansible.com/ansible/playbooks_delegation.html#run-once>
~~~
- name: Début installation, envoie email
run_once: true
@ -834,8 +807,6 @@ Pour une exécution locale, on peut aussi utiliser l'attribut `local_action`.
Si cet attribut est utilisé avec `delegate_to`, alors cette machine sera la seule à exécuter cette tâche. Sinon, c'est la première dans la liste de l'inventaire.
<https://docs.ansible.com/ansible/playbooks_delegation.html#run-once>
### Appliquer une tâche à une liste (tableau) -> boucle
#### with_items
@ -966,7 +937,7 @@ Ou donner une condition
~~~
$ ansible -m setup <hostname>
service.evolix.net | SUCCESS => {
HOSTNAME | SUCCESS => {
"ansible_facts": {
(…)
"ansible_architecture": "x86_64",