[WIP] révision du HowtoAnsible

This commit is contained in:
Jérémy Lecour 2017-01-13 15:47:03 +01:00 committed by Jérémy Lecour
parent c735ff6efa
commit 09caa18ba9
2 changed files with 291 additions and 143 deletions

View file

@ -1,23 +1,24 @@
**Cette page a été importée automatiquement de notre ancien wiki mais n'a pas encore été révisée.** ---
categories: web
title: Howto Ansible : automatisation d'infrastructure
---
# Howto Ansible * Documentation : <http://docs.ansible.com/>
<http://docs.ansible.com/> Ansible est un outil d'automatisation de configuration et gestion de serveurs : il permet le déploiement de logiciels et l'execution de tâches via une connexion SSH.
Ansible est une plateforme de configuration et gestion de serveurs : il permet le déploiement de logiciels et l'execution de tâches via une connexion SSH. Ansible fonctionne sans agent sur les serveurs (*agent-less*) et selon le concept d'*[idempotence](https://fr.wikipedia.org/wiki/Idempotence)* : on décrit l'état d'un serveur et des actions seront executées dans le but de rendre le serveur conforme à cette description.
Ansible est *agent-less* et utilise le concept d*[idempotence](https://fr.wikipedia.org/wiki/Idempotence)* : on décrit l'état d'un serveur dans un fichier YAML appelé *playbook* et des actions seront executées dans le but de rendre le serveur conforme à cette description.
On pourra relancer Ansible plusieurs fois, l'état final reste le même : seules les actions nécessaires seront exécutées. On pourra relancer Ansible plusieurs fois, l'état final reste le même : seules les actions nécessaires seront exécutées.
Ansible peut exécuter des actions sur des serveurs distants sous : Ansible peut exécuter des actions sur des serveurs distants sous :
* *Debian* 6 et supérieur (nécessite uniquement _Python_ ce qui est le cas par défaut) * *Debian 6* et supérieur (nécessite uniquement _Python_ ce qui est le cas par défaut)
* Debian 4 / 5 : voir [#AnsiblesurdesvieillesversionsDebian] * *Debian 4 / 5* : voir [#AnsiblesurdesvieillesversionsDebian]
* *FreeBSD* et *OpenBSD* : TODO => décrire pré-requis * *FreeBSD* et *OpenBSD* : TODO => décrire pré-requis
## Installation ## Installation
Nous utilisons Ansible 2.0.2 (disponible via <http://pub.evolix.net/jessie/)> sous Debian 8 : Nous utilisons actuellement Ansible 2.0.2 (disponible via <http://pub.evolix.net/jessie/)> sous Debian 8 :
~~~ ~~~
# apt install --allow-unauthenticated ansible=2.0.2.0-1~bpo8+1 # apt install --allow-unauthenticated ansible=2.0.2.0-1~bpo8+1
@ -61,15 +62,55 @@ $ ansible-playbook PLAYBOOK_WITH-SUDO.yml --limit HOSTNAME --ask-become-pass
Options utiles pour [ansible-playbook](https://manpages.debian.org/cgi-bin/man.cgi?query=ansible-playbook&apropos=0&sektion=0&manpath=Debian+unstable+sid&format=html&locale=en) : Options utiles pour [ansible-playbook](https://manpages.debian.org/cgi-bin/man.cgi?query=ansible-playbook&apropos=0&sektion=0&manpath=Debian+unstable+sid&format=html&locale=en) :
* *-vvvv* : très verbeux (utile notamment pour debug SSH quand on a une erreur _unreachable_) * `-vvvv` : très verbeux (utile notamment pour debug SSH quand on a une erreur _unreachable_)
* *-k / --ask-pass* : demande le mot de passe utilisateur (si connexion SSH sans clé) * `-k` / `--ask-pass` : demande le mot de passe utilisateur (si connexion SSH sans clé)
* *-K / --ask-become-pass* : demande le mot de passe utilisateur pour sudo * `-K` / `--ask-become-pass` : demande le mot de passe utilisateur pour sudo
* *-l / --limit HOSTNAME* : limite la connexion au serveur HOSTNAME (attention, par défaut c'est *all*, cf `/etc/ansible/hosts`) * `-l` / `--limit HOSTNAME` : limite la connexion au serveur HOSTNAME (attention, par défaut c'est *all*, cf `/etc/ansible/hosts`)
* *-f / --forks N* : nombre de process lancé en parallèle (par défaut 5)... peut être utile de mettre à 1 pour ne pas paralléliser * `-f` / `--forks N` : nombre de process lancé en parallèle (par défaut 5)… peut être utile de mettre à 1 pour ne pas paralléliser
## Les éléments d'Ansible
L'utilisation d'Ansible se fait principalement avec un **playbook**. C'est l'élément clé, qui peut suffir à réaliser des tâches utiles. Il s'agit d'un fichier qui décrit la succession d'une ou plusieurs séries d'actions (des *play*). Chaque *play* indiques quelques réglages généraux comme le groupe de serveurs concernés, la manière de devenenir administrateur, quels fichiers de variables charger…
Un playbook va ensuite dérouler des _actions_ qui seront organisées en _roles_, _tasks_ et _handlers_.
Une **action** est l'invocation d'une fonctionnalité particulière fournie par un module. Exemple, pour s'assurer de l'absence d'un fichier :
```
- file: path=/etc/cron.daily/apticron state=absent
```
Les actions peuvent être listées dans la partie **tasks** du playbook et peuvent être aussi déportées dans un fichier et inclus dans le playbook.
Les **handlers** sont des actions qui ne sont exécutées que si une autre action en a fait la demnde, via l'attribut `notify`.
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 une structure conventionnelle :
```
foo
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
└── main.yml
```
La partie **inventory** correspond à la description de l'inventaire des serveurs à configurer et inclus un mécanisme de configuration individuel et par groupe. Nous y revenons plus loin.
## Howto Playbook ## Howto Playbook
Exemple de playbook `hello_world.yml` : Exemple de playbook très simple :
~~~{.yaml} ~~~{.yaml}
--- ---
@ -81,11 +122,44 @@ Exemple de playbook `hello_world.yml` :
# vim:ft=ansible: # vim:ft=ansible:
~~~ ~~~
Un playbook est un ensemble de "plays" ; un "play" contient au minimum *hosts* (serveurs cible) et *tasks* (ensemble de tâches), et peut également contenir : Un playbook plus complexe :
~~~{.yaml}
---
- hosts: all
gather_facts: yes
become: yes
vars_files:
- 'vars/main.yml'
vars:
external_roles: ~/GIT/ansible-roles
external_tasks: ~/GIT/ansible-public/tasks
pre_tasks:
- name: Minifirewall is stopped (temporary)
service:
name: minifirewall
state: stopped
roles:
- "{{ external_roles }}/minifirewall"
post_tasks:
- include: "{{ external_tasks }}/commit_etc_git.yml"
vars:
commit_message: "Ansible run capitaldata-firewall.yml"
handlers:
- name: restart minifirewall
service:
name: minifirewall
state: restarted
# vim:ft=ansible:
~~~
* *vars* : des variables
* *handlers* : des actions déclenchées si une tâche a été exécutée (via l'option `notify`)
* *roles* : des rôles pour avoir des playbooks organisés et modulaires
### Modules pour tasks ### Modules pour tasks
@ -95,171 +169,245 @@ Pour avoir la liste des modules utilisables dans *tasks* : `ansible-doc -l`
Voici quelques exemples : Voici quelques exemples :
* Module [command](http://docs.ansible.com/ansible/command_module.html) :
~~~{.yaml} ~~~{.yaml}
--- - command: date
- name : exemple avec le module COMMAND ~~~
command: date
- name : exemple avec le module SHELL * Module [shell](http://docs.ansible.com/ansible/shell_module.html) :
shell: time date
- name: exemple avec le module SERVICE ~~~{.yaml}
service: name=<httpd> state=restarted - shell: cat foo.txt | grep bar
~~~
- name: exemple avec le module FILE * Module [file](http://docs.ansible.com/ansible/file_module.html) :
file: path=/etc/cron.daily/apticron state=absent
- name : exemple avec le module COPY ~~~{.yaml}
copy: src=files/foo dest=/etc/bar owner=root group=root mode=0644 - file:
path: /etc/cron.daily/apticron
state: absent
~~~
- name : exemple avec le module LINEINFILE * Module [copy](http://docs.ansible.com/ansible/copy_module.html) :
lineinfile: dest=/etc/evocheck.cf insertafter=EOF line="IS_APTICRON=0" regexp="^IS_APTICRON="
- name : exemple avec le module USER ~~~{.yaml}
user: - copy
src: files/foo
dest: /etc/bar
owner: root
group: root
mode: "644"
~~~
* Module [lineinfile](http://docs.ansible.com/ansible/lineinfile_module.html) :
~~~{.yaml}
- lineinfile:
dest: /etc/evocheck.cf
insertafter: EOF
line: "IS_APTICRON=0"
regexp: "^IS_APTICRON="
~~~
* Module [blockinfile](http://docs.ansible.com/ansible/blockinfile_module.html) :
~~~{.yaml}
- blockinfile:
dest: /etc/apache2/envvars
block: |
## Set umask for writing by Apache user.
## Set rights on files and directories written by Apache
~~~
* Module [replace](http://docs.ansible.com/ansible/replace_module.html) :
~~~{.yaml}
- replace:
dest: /etc/ssh/sshd_config
regexp: '^(Match User ((?!{{ name }}).)*)$'
replace: '\1,{{ name }}'
~~~
* Module [ini_file](http://docs.ansible.com/ansible/ini_file_module.html) :
~~~{.yaml}
- ini_file:
dest: /root/.my.cnf
section: client
option: user
value: root
mode: "640"
~~~
* Module [user](http://docs.ansible.com/ansible/user_module.html) :
~~~{.yaml}
- user:
state: present state: present
name: {{ name }} name: "{{ name }}"
comment: 'John Doe' comment: 'John Doe'
shell: /bin/bash shell: /bin/bash
groups: adm groups: adm
append: yes append: yes
password: '$6$k/Fg76xH' password: '$6$k/Fg76xH'
~~~
- name : exemple avec le module REPLACE * Module [stat](http://docs.ansible.com/ansible/stat_module.html) :
replace:
dest: /etc/ssh/sshd_config
regexp: '^(Match User ((?!{{ name }}).)*)$'
replace: '\1,{{ name }}'
- name : exemple avec le module STAT ~~~{.yaml}
stat: path=/etc/sudoers.d/foo - stat:
path: /etc/sudoers.d/foo
register: foo_sudoers_file register: foo_sudoers_file
~~~
- name : exemple avec le module APT * Module [apt](http://docs.ansible.com/ansible/apt_module.html) :
apt:
name: '{{ item }}'
state: latest
allow_unauthenticated: yes
update_cache: yes
cache_valid_time: 3600
with_items:
- vim
- htop
- name : exemple ~~~{.yaml}
- apt:
name: '{{ item }}'
state: latest
update_cache: yes
cache_valid_time: 3600
with_items:
- vim
- htop
~~~
* Module [apt_repository](http://docs.ansible.com/ansible/apt_repository_module.html) :
~~~{.yaml}
- name: exemple
apt_repository: apt_repository:
repo: "deb http://mirror.evolix.org/jessie stable main"
state: present
~~~
- name: exemple avec le module INI_FILE * Module [mysql_user](http://docs.ansible.com/ansible/mysql_user_module.html) :
ini_file:
dest: /root/.my.cnf
section: client
option: user
value: root
mode: 0640
- name: exemple avec le module MYSQL_USER (nécessite le paquet python_mysqldb) ~~~{.yaml}
mysql_user: - mysql_user:
name: mysqladmin name: mysqladmin
password: my_password password: my_password
priv: "*.*:ALL,GRANT" priv: "*.*:ALL,GRANT"
state: present state: present
config_file: /root/.my.cnf config_file: /root/.my.cnf
update_password: on_create update_password: on_create
~~~
- name: exemple avec l'ajout de plusieurs lignes dans un fichier * Module [sysctl](http://docs.ansible.com/ansible/sysctl_module.html) :
blockinfile:
dest: /etc/apache2/envvars
block: |
## Set umask for writing by Apache user.
## Set rights on files and directories written by Apache
~~~{.yaml}
- name: exemple - name: exemple
systcl: sysctl:
name: vm.max_map_count
value: 262144
sysctl_file: /etc/sysctl.d/elasticsearch.conf
~~~
- name: exemple * Module [alternatives](http://docs.ansible.com/ansible/alternatives_module.html) :
alternatives:
- name: exemple ~~~{.yaml}
service: - alternatives:
name: editor
path: /usr/bin/vim.basic
~~~
- name: exemple * Module [service](http://docs.ansible.com/ansible/service_module.html) :
mount:
~~~{.yaml}
- name: exemple pour redémarrer un service (compatible avec sysvinit, systemd…)
service: nginx
state: restarted
~~~ ~~~
#### replace: vs lineinfile: #### replace: vs lineinfile:
* lineinfile: si regexp= n'est pas matché... il insère quand même la ligne ! avec lineinfile: regexp= n'est pas une condition pour l'insertion mais une condition pour remplacer au lieu d'insérer ! * `lineinfile`: si `regexp:` n'est pas matché… il insère quand même la ligne ! avec `lineinfile` `regexp` n'est pas une condition pour l'insertion mais une condition pour remplacer au lieu d'insérer !
* avec lineinfile: sauf cas tordus, regexp= doit matcher line= (sinon il va insérer line= à l'infini !) * avec `lineinfile`: sauf cas tordus, `regexp` doit matcher `line` (sinon il va insérer la valeur de `line` à l'infini !)
* lineinfile: va 1. regarder si regexp= existe et il remplace la dernière ligne, 2. si regexp n'existe pas, il ajoute line= (sans d'autre condition... même si elle existe déjà) * `lineinfile`: va 1. regarder si `regexp` existe et il remplace la dernière ligne, 2. si `regexp` n'existe pas, il ajoute `line` (sans d'autre condition… même si elle existe déjà)
* replace: il va remplacer uniquement si regex est matché, logique (comme sed) * `replace`: il va remplacer uniquement si `regex` est matché, logique (comme la commande `sed`)
* si l'on veut utiliser une référence (\1) dans line# avec lineinfile:> erreur, il faut utiliser replace: * si l'on veut utiliser une référence (`\1`) dans `line` avec `lineinfile`, ça donne une erreur, il faut utiliser `replace`
* avec lineinfile: backrefs=yes c'est pour utiliser une référence au sein de regexp= (et non pas au sein de line=) * avec `lineinfile` + `backrefs: yes` c'est pour utiliser une référence au sein de `regexp` (et non pas au sein de `line`)
### vars ### vars
Gestion des variables : Gestion des variables :
~~~ ~~~{.yaml}
vars: vars:
ip: 31.170.9.129
conf_file: /etc/foo.conf
ip: 31.170.9.129 tasks:
conf_file: /etc/foo.conf - command: echo {{ ip }} >> {{ conf_file }}
tasks:
- shell: echo {{ ip }} {{ conf_file }}
~~~ ~~~
Pour gérer de nombreuses variables dans un projet, voici l'arborescence conseillée : Pour gérer de nombreuses variables dans un projet, on peut stocker toutes celles qui correspondent à un groupe de serveur dans un fichier portant le nom du groupe, ainsi que toutes celle d'un serveur en particulier dans un fichier du nom du serveur. Voici l'arborescence conseillée :
~~~ ~~~
group_vars/ └── inventory
group1 # here we assign variables to particular groups    ├── group_vars
group2 # "" │   └── group1.yml
host_vars/ │   └── group2.yml
hostname1 # if systems need specific variables, put them here   └── host_vars
hostname2 # ""    └── hostname1.yml
   └── hostname2.yml
~~~ ~~~
Les groupes sont définis dans le fichier d'[inventaire](http://docs.ansible.com/ansible/intro_inventory.html).
### Handlers ### Handlers
La directive `notify` permet de déclencher un `handler` après la fin d'éxecution d'une tâche : La directive `notify`, disponible pour tous les modules, permet de déclencher un `handler`.
~~~ 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.
Les handlers servent le plus souvent à redémarrer des programmes.
~~~{.yaml}
tasks: tasks:
- apt: ... - name: copy Apache configuration
notify: Done copy: (…)
notify: Restart Apache
handlers: handlers:
- name: Done - name: Restart Apache
shell: echo "It's done" service:
name: apache2
state: restarted
~~~ ~~~
Le redémarrage d'un service devrait toujours être effectué via handler. Dans des rôles longs, il ets conseillé de purger les handlers de temps en temps (en fin de groupe d'action) pour que si le playbook ets interrompu les handlers ne soient pas exécutés alors que l'action qui les a déclenchés a bien eu lieu. On insère alors l'action suivante :
```{.yaml}
- meta: flush_handlers
```
### Tags ### Tags
<https://docs.ansible.com/ansible/playbooks_tags.html> <https://docs.ansible.com/ansible/playbooks_tags.html>
Hormis le fait de ranger/trier chaque tâche dans une catégorie, permet de limiter/exclure des tâches. Hormis le fait de ranger/trier chaque tâche dans une catégorie, ils permettent de limiter/exclure des tâches.
~~~ ~~~{.yaml}
- name: Coucou - name: Coucou
debug: msg="Saloute!" debug:
msg: "Saloute!"
tags: message tags: message
...
~~~ ~~~
Pour ne pas afficher les messages : Pour ne pas afficher les messages :
~~~ ~~~
$ ansible-playbook ... --skip-tags "message" $ ansible-playbook (…) --skip-tags "message"
~~~ ~~~
On peut appliquer des tags à des rôles, ou voir directement n'éxecuter que certains tags : On peut appliquer des tags à des rôles, ou voir directement n'éxecuter que certains tags :
~~~ ~~~
$ ansible-playbook ... --tags "configuration,packages" $ ansible-playbook (…) --tags "configuration,packages"
~~~ ~~~
Note : on peut également _taguer_ des `include`. Note : on peut également _taguer_ des `include`.
@ -270,17 +418,20 @@ Note : on peut également _taguer_ des `include`.
Pour shell, on a le droit à `.stdout`, `.stderr`, `.rc`, ... Mais cela dépend bien des valeurs de retour du module. Pour shell, on a le droit à `.stdout`, `.stderr`, `.rc`, ... Mais cela dépend bien des valeurs de retour du module.
Mais pour être sûr des valeurs initialisées, on peut utiliser `debug` afin d'analyser le résultat. Mais pour être sûr des valeurs initialisées, on peut utiliser `debug` afin d'analyser le résultat.
~~~ ~~~{.yaml}
- stat: path=/etc/passwd - stat:
path: /etc/passwd
register: st register: st
- debug: var=st - debug:
var: st
- fail: msg="Whoops! file ownership has changed" - fail:
msg: "Whoops! file ownership has changed"
when: st.stat.pw_name != 'root' when: st.stat.pw_name != 'root'
~~~ ~~~
Pour certains modules, `register` est un passage obligatoire pour une utilisation cohérente des éléments (stat...). Pour certains modules, `register` est un passage obligatoire pour une utilisation cohérente des éléments (stat).
## Configuration ## Configuration
@ -288,13 +439,10 @@ Pour certains modules, `register` est un passage obligatoire pour une utilisatio
La configuration est lue dans l'ordre suivant : La configuration est lue dans l'ordre suivant :
~~~ * `ANSIBLE_CONFIG` (variable d'environnement)
* `./ansible.cfg`
* ANSIBLE_CONFIG (an environment variable) * `~/.ansible.cfg`
* ansible.cfg (in the current directory) * `/etc/ansible/ansible.cfg`
* .ansible.cfg (in the home directory)
* /etc/ansible/ansible.cfg
~~~
### Fichier "inventory" ### Fichier "inventory"
@ -308,9 +456,9 @@ Exemple:
~~~ ~~~
hostname.internal hostname.internal
[<httpservers>] [httpservers]
machine[01:57].example.com machine[01:57].example.com
<http.example.com:2222> http.example.com:2222
[dbservers] [dbservers]
machine12.example.com machine12.example.com
@ -319,7 +467,7 @@ m[a:o]chine52.example.com
alias ansible_port=2222 ansible_host=192.168.1.50 alias ansible_port=2222 ansible_host=192.168.1.50
[client] [client]
host1 <http_port=80> maxRequestsPerChild=808 #des variables qui seront automatiquement auto-completé lié à cet host host1 http_port=80 maxRequestsPerChild=808 # des variables qui seront automatiquement auto-completées liées à cet host
[commercant] [commercant]
mercerie mercerie
@ -330,15 +478,15 @@ ntp_server=ntp.mercerie.example.com
proxy=proxy.mercerie.example.com proxy=proxy.mercerie.example.com
~~~ ~~~
* *hostname.internal* : host hors groupe * `hostname.internal` : host hors groupe
* *[<httpservers>]* : le nom du groupe (pour les serveurs <http).> Les noms de hosts qui suivent appartiendront à ce 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_ * `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 * `http.evolix.net:2222` : ansible se connecte par ssh, et _http.evolix.net_ a un port ssh d'écoute différent qui est 2222
* *[dbservers]* : groupe pour les serveurs de base de donnée * `[dbservers]` : groupe pour les serveurs de base de donnée
* *machine50.example.com* : cette machine est déjà présente dans le groupe _<httpservers_,> mais sera aussi accessible à partir du groupe _dbservers_ * `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'est pas un vrai FQDN mais pointera vers _192.168.1.50_ car on a indiqué des variables propre à _ansible_. Il est aussi disponible `ansible_connection` (local ou ssh) ou `ansible_user` (le nom de l'utilisateur de la machine distante avec lequel _ansible_ se connectera en ssh) * `alias ansible_port=2222 ansible_host=192.168.1.50` : la machine alias n'est pas un vrai FQDN mais pointera vers _192.168.1.50_ car on a indiqué des variables propre à Ansible. Il est aussi disponible `ansible_connection` (local ou ssh) ou `ansible_user` (le nom de l'utilisateur de la machine distante avec lequel _ansible_ se connectera en ssh)
* *host1 <http_port=80> maxRequestsPerChild=808* : des variables qui seront automatiquement auto-completé lié à host1 * `host1 http_port=80 maxRequestsPerChild=808` : des variables qui seront automatiquement auto-completé lié à host1
* *[commercant:vars]* : des variables qui seront liés au groupe _commercant_. On peut aussi créer des groupes de groupes en utilisant `:children` * `[commercant:vars]` : des variables qui seront liés au groupe _commercant_. On peut aussi créer des groupes de groupes en utilisant `:children`
On peut aussi découper le fichier "inventory" selon les groupes et les variables : [<http://docs.ansible.com/ansible/intro_inventory.html#splitting-out-host-and-group-specific-data>]. On peut aussi découper le fichier "inventory" selon les groupes et les variables : [<http://docs.ansible.com/ansible/intro_inventory.html#splitting-out-host-and-group-specific-data>].
@ -348,18 +496,18 @@ Les variables propres à Ansible : [<http://docs.ansible.com/ansible/intro_inven
Options utiles (TODO : à revoir) : Options utiles (TODO : à revoir) :
* *display_args_to_stdout* : mettre à `True` si on veut voir tout le contenu du _tasks_ executé pour chaque étape écrit sur _stdout_ * `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)_ * `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)_
* *error_on_undefined_vars* : mettre à `True` pour être sûr que le script ansible s'arrête si une variable n'est pas défini (alors qu'il y a utilisation de cette dernière dans une _task_) * *error_on_undefined_vars* : mettre à `True` pour être sûr que le script ansible s'arrête si une variable n'est pas défini (alors qu'il y a utilisation de cette dernière dans une _task_)
* *force_color* : mettre à `1` pour forcer la couleur * `force_color` : mettre à `1` pour forcer la couleur
* *forks* : le nombre de processus en parallèle possible lors déploiement du script ansible sur nombreux _hosts_. * `forks` : le nombre de processus en parallèle possible lors déploiement du script ansible sur nombreux _hosts_.
* *module_lang* : changer la langue * `module_lang` : changer la langue
* *module_name* : le module par défaut (`command`) lors de l'utilisation de la commande `ansible` * `module_name` : le module par défaut (`command`) lors de l'utilisation de la commande `ansible`
* *hosts* : accès vers les _hosts_ par défaut (`all`) * `hosts` : accès vers les _hosts_ par défaut (`all`)
* *private_key_file* : le chemin pour la clé pem * `private_key_file` : le chemin pour la clé pem
* *remote_port* : le port ssh par défaut (`22`) * `remote_port` : le port ssh par défaut (`22`)
* *remote_user* : l'utilisateur pour la connexion ssh par défaut (`root`) * `remote_user` : l'utilisateur pour la connexion ssh par défaut (`root`)
* *retry_files_enabled* : mettre à `True` pour la création de fichier `.retry` après une failure de ansible pour reprendre le travail précédent - ajouté en argument dans l'appel de la commande * `retry_files_enabled` : mettre à `True` pour la création de fichier `.retry` après une failure de ansible pour reprendre le travail précédent - ajouté en argument dans l'appel de la commande
## Erreurs ## Erreurs