Améliorations
This commit is contained in:
parent
66984e0dac
commit
21485e74a4
115
HowtoAnsible.md
115
HowtoAnsible.md
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue