Table des matières

Introduction

Ansible est un outil open source, de gestion de configuration et d’automatisation de déploiement des applications. Aujourd'hui, la plupart des outils d’automatisation ( Chef/Puputt ) se basent sur un agent hôte distant, mais Ansible n’a besoin que d’une connexion SSH et Python (2.4 ou ultérieure) pour être installé sur les nœuds distants et pour effectuer ses actions.

Le but est de simplifier l'administration au quotidien, notamment pour déployer des changements de configuration de service ou l'installation d'une nouvelle machine.

Comment fonctionne Ansible ?

Ansible est déployé en deux types de serveurs : Serveur de contrôle et les nœuds.

Le serveur de contrôle, où Ansible est installé et les nœuds sont gérés par cette machine de contrôle via SSH.

Le serveur de contrôle (Ansible) déploie des modules en utilisant le protocole SSH et ces modules sont stockés temporairement sur les nœuds distants et communiquent avec le master Ansible via une connexion JSON sur la sortie standard.

Ansible est sans agent, ce qui signifie que vous n’avez pas besoin d'installer l’agent sur les nœuds distants, donc il n'y a pas des démons ou des programmes qui s'exécutent en arrière plan quand Ansible ne gère pas les nœuds.

Ansible peut gérer 100 nœuds à partir d’un seul système via une connexion SSH et l'ensemble de l’opération peut être manipulé et exécuté par une seule commande 'ansible'. Mais, dans certains cas, lorsque vous aurez besoin d’exécuter plusieurs commandes pour un déploiement, là, vous pourrez construire des Playbooks.

Les Playbooks sont des fichiers en format YAML qui regroupent des commandes et qui permettent d’effectuer des tâches multiples.

Comparaison avec les autres produits

Puppet

L’outil le plus répandu de gestion de la configuration :

Capable de piloter des systèmes :

Côté client

Chaque client possède un agent (qui tourne en daemon de manière habituelle).

L’agent a pour but de contacter le master :

Côté serveur

Le serveur est le lieu d’exécution du Puppet Master (port 8140). C’est le lieu de :

Langage de configuration et abstraction des ressources

Puppet utilise un langage déclaratif propre pour définir les éléments de configuration, nommés des “ressources”.

Les ressources définissent l’état du système voulu :

Chef

Chef a été crée par des anciens de PuppetLabs :

Il souhaite résoudre des bottlenecks de Puppet (résolus depuis). Son langage de configuration est du Ruby (et donc besoin de le connaitre).

Dernièrement son coeur a été ré-écrit en Erlang.

SaltStack

C’est un projet de nouvelle génération (2011), comme Ansible et écrit en Python.

Initialement basé sur ZeroMQ, il possède désormais une alternative (RAET) pour permettre une meilleure scalabilité.

Il possède son propre langage de configuration. Salt est capable de fonctionner en :

Mise en œuvre de Ansible

Installer Ansible

Ansible est installé uniquement sur une machine de management. L’installation peut être faite

Python (> 2.5, < 3) doit être installé sur les machines sur lesquelles Ansible devra agir.

Pour les machines utilisant selinux par défaut, il faudra installer le paquet python-selinux (éventuellement par Ansible).

Pour installer Ansible sur Centos/RHEL, il suffit de lancer la commande :

# yum install epel-release

Après avoir configuré le repository EPEL, vous pouvez installer Ansible en utilisant la commande suivante :

# yum -y install ansible

Mise en place de l’inventaire

L'inventaire définit la liste des machines sur lesquelles Ansible est susceptible d'agir. Ces machines sont organisées en groupes, une machine pouvant appartenir à plusieurs groupes.

Des variables arbitraires peuvent être associées aux machines et aux groupes. Des variables prédéfinies permettent de modifier le comportement d'Ansible, notamment pour définir les informations d’authentification.

Le fichier inventaire est '/etc/ansible/hosts' par défaut. Il peut être modifié dans la configuration Ansible, ou spécifié lors de l'exécution des commandes Ansible.

Les inventaires sont des fichiers au format INI.

Chaque section définit un groupe de machines :

[webservers]
www1.oowy.lan
www2.oowy.lan
 
[dns]
ns1.oowy.lan
ns2.oowy.lan

Il est également possible de définir des “groupes de groupes” :

[dns_ext1_oowy.lan]
dns1.ext1_oowy.lan
dns2.ext1.oowy.lan
 
[dns_ext2_oowy.lan]
dns1.ext2.oowy.lan
dns2.ext2.oowy.lan
 
[dns:children]
dns_ext1_oowy.lan
dns_ext2_oowy.lan

Variables

Les variables sont définies

Définition de variables pour chaque hôte :

[dns]
ns1.oowy.lan ansible_ssh_user=ansible type=master
ns2.oowy.lan ansible_ssh_user=ansible type=slave

La variable ansible_ssh_user est utilisée par Ansible pour établir les connexions SSH avec le bon utilisateur.

La variable type n'est pas utilisée par défaut par Ansible, mais pourra l'être par les rôles et playbooks utilisateur.

Si des variables sont communes à tous les hôtes, elle peuvent être définies dans une section du fichier inventaire :

[dns]
ns1.oowy.lan type=master
ns2.oowy.lan type=slave
 
[dns:vars]
ansible_ssh_user=ansible

Il est également possible de définir les variables dans des fichiers placés dans les dossiers group_vars et host_vars. Ces fichiers utilisent le langage YAML pour définir les variables.

L'exemple précédent pourrait être réécrit en séparant les informations dans plusieurs fichiers.

Contenu de /etc/ansible/hosts :

[dns]
ns1.oowy.lan
ns2.oowy.lan

Contenu de /etc/ansible/group_vars/dns :

ansible_ssh_user: ansible

Contenu de /etc/ansible/host_vars/ns1.oowy.lan :

type: master

Contenu de /etc/ansible/host_vars/ns2.oowy.lan :

type: slave

CLI Ansible

Ansible fournit plusieurs outils en ligne de commande :

Le module ping permet de valider l'inventaire, et l'accès aux machines distantes. La commande ansible permet son exécution :

[ user@srv ~]$ ansible -i hosts dns -m ping

L’option -i spécifie le chemin vers l’inventaire (s’il n’est pas placé à l’endroit par défaut attendu par Ansible).

dns est le groupe de machines sur lesquelles la commande sera executée. La valeur all permet de déclencher une exécution sur toutes les machines définies dans l’inventaire.

L’option -m spécifie le module Ansible à utiliser sur les hôtes.

Gestion des accès

L'accès SSH aux hôtes peut être explicité de plusieurs manières :

Ligne de commande

La commande ansible fournit plusieurs arguments pour spécifier les paramètres d'authentification :

Cette méthode d'authentification s'avère vite contraignante.

Configuration de la machine de management

Il est préférable de configurer la machine de management et les hôtes distants pour ne pas utiliser de mots de passe (ni pour SSH, ni pour sudo). Cela implique :

La création d'une clé SSH se fait grâce à la commande ssh-keygen :

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
...

La commande ssh-copy-id permet la copie de la clé publique sur les hôtes distants :

$ ssh-copy-id ansible@dns1.oowy.lan
$ ssh ansible@dns1.oowy.lan # authentification sans mot de passe

Le login utilisateur pour chaque hôte peut être spécifié dans l'inventaire, mais également dans le fichier de configuration SSH local :

$ cat ~/.ssh/config
Host dns1.oowy.lan
    User ansible

Si un compte utilisateur autre que root est utilisé, sudo peut être configuré pour ne pas demander de mot de passe lors de son utilisation :

$ cat /etc/sudoers.d/ansible
ansible ALL=(ALL) NOPASSWD: ALL

Pour consolider la sécurité d’accès aux hôtes distants, il est possible de restreindre les accès à l'utilisateur Ansible

Fichier de configuration

Ansible peut fonctionner sans modifier sa configuration par défaut, mais quelques éléments peuvent influer sur son comportement.

La configuration d'Ansible se fait dans un fichier au format INI. Ansible cherche ce fichier à plusieurs endroits du système, dans cet ordre :

  1. variable d’environnement ANSIBLE_CONFIG
  2. ansible.cfg dans le dossier courant
  3. ~/.ansible.cfg
  4. /etc/ansible/ansible.cfg

De nombreuses options de configuration sont disponibles, parmi lesquelles on trouve :

[defaults]/fork : Nombre de processus à exécuter en parallèle

[defaults]/inventory : Emplacement du fichier d’inventaire (voir Mise en place de l’inventaire)

[defaults]/library : Emplacement de modules Ansible (dossiers séparés par :)

[defaults]/roles_path : Emplacement de roles Ansible (dossiers séparés par :)

[defaults]/host_key_checking : A définir à True pour éviter la validation des clés SSH du serveur.

[ssh_connection]/pipelining : A définir à True pour limiter le nombre de connexions à un hôte.

L'ensemble des directives utilisables dans le fichier de configuration est disponible sur la documentation Ansible.

Utilisation des principaux modules adhoc

Les modules Ansible

Les modules sont la base des actions exécutées par Ansible. Chaque module traite d’un type d’action spécifique (modification d’un fichier, exécution d’une commande, récupération d’informations, …).

Les modules acceptent des arguments, généralement sous la forme clé=valeur. Ansible fournit un ensemble de modules (core) dont la liste est accessible via la commande ansible-doc –list.

La commande ansible-doc permet également d’afficher la documentation de chaque module : ansible-doc <MODULE>.

Par exemple :

$ ansible-doc apt

On peut aussi les retrouver sur le web (parfois plus lisible) : http://docs.ansible.com/ansible/modules_by_category.html

La majorité des modules peuvent être utilisés via la commande ansible, mais certains ne fonctionnent qu’au sein de playbooks (par exemple le module template).

La syntaxe de base pour l’utilisation de modules avec la commande ansible est :

$ ansible (hote/group/all) -m MODULE [-a "arg1=val1 [arg2=val2]"]

Par exemple, pour l'installation d’un paquet par le module apt :

$ ansible (hote/group/all) -m apt -a "name=vim state=present"

L'option -m spécifie le module à utiliser. L'option -a spécifie les arguments à passer au module. L'exécution d’un module peut retourner 3 états différents :

En plus de cet état, des données au format JSON sont retournées par Ansible :

$ ansible target -m apt -a "name=vim state=present"
target | success >> {
   "changed": true,
   "stderr": "",
   "stdout": "Reading package lists..."
}
 
$ ansible target -m apt -a "name=vim state=present"
target | success >> {
   "changed": false
}

ping

Le module ping est utile pour valider la configuration de l’inventaire Ansible. Ce module ne prend pas d'argument.

$ ansible all -m ping
dns1.oowy.lan | success >> {
"changed": false,
"ping": "pong"
}
dns2.oowy.lan | FAILED => SSH Error: data could not be sent to the remote host.
   Make sure this host can be reached over ssh

setup

Le module setup n'exécute aucune action sur l'hôte, mais retourne un ensemble de facts : des informations sur l'hôte.

Ces facts couvrent un ensemble d’éléments, parmi lesquels des informations sur :

$ ansible dns1.oowy.lan -m setup
dns1.oowy.lan | success >> {
   "ansible_facts": {
       "ansible_all_ipv4_addresses": [
           "10.10.10.10"
       ],
        ...
   }
}

shell / command

Les modules shell et command permettent d'exécuter des commandes sur les hôtes.

command n'utilise pas le shell pour exécuter la commande, et ne peut donc pas utiliser les variables d'environnements, les pipes ou les redirections.

shell exécute la commande via un shell, et permet l'utilisation des éléments non permis par le module command.

Ces deux modules ont des arguments similaires. On trouve notamment :

Enfin la commande à exécuter est également passée sous forme d'argument du module.

$ ansible all -m command -a "ping -c 2 google.com"
$ ansible all -m shell -a "echo foo > /etc/bar creates=/etc/bar"

user

Le module user permet de gérer les utilisateurs (/etc/passwd) sur les hôtes, leurs mots de passe (/etc/shadow), leur homedir, …

file

Le module file permet de gérer les droits sur les fichiers (propriétaire, groupe, droits d’accès), s'assurer qu'il s'agisse de lien ou répertoire, …

service

Le module service permet de gérer les services systèmes :

Exemples :

# Redémarrage de bind sur tous les serveurs DNS
$ ansible dns -m service -a "name=bind9 state=restarted"
 
# Activation au démarrage
$ ansible dns -m service -a "name=bind9 enabled=yes"

yum / apt / zypper / dnf

Ces modules permettent de gérer l’installation, la mise à jour et la suppression de paquets :

# Pour RedHat et distributions dérivées
$ ansible dns -m yum -a "name=named state=latest"
 
# Pour Debian et distributions dérivées
$ ansible dns -m apt -a "name=bind9 state=latest"

Des modules complémentaires permettent de gérer les dépôts :

Les playbooks Ansible

Intérêt

Utiliser les modules les uns après les autres via la commande ansible ne permet pas de profiter des fonctionnalités d'orchestration d’Ansible.

Les playbooks sont la description d’un ensemble de tâches à effectuer de manière séquentielle, sur tout ou partie de l’inventaire.

Chaque tâche (task) d’un playbook utilise un module Ansible. Les playbooks offrent cependant des fonctionnalités supplémentaires :

Les playbooks se définissent en langage YAML.

Un playbook est constitué au minimum d’une liste d’actions à effectuer sur un ensemble d’hôtes, définis dans l'inventaire.

On trouve au minimum dans chaque playbook :

On peut également trouver :

Exemple de playbook simple :

- hosts: dns
  become: yes
  tasks:
  - name: Installing vim
    package:
      name: vim
      state: present
    tags:
    - vim

La commande ansible-playbook

L'exécution du playbook est déclenchée via la commande ansible-playbook :

$ ansible-playbook mon_playbook.yml

Par défaut toutes les règles du playbook s’exécuteront sur tous les hôtes concernés.

Il est possible de limiter les actions :

Par exemple :

$ ansible-playbook mon_playbook.yml --tags vim -l dns1.oowy.lan

Syntaxe YAML

Ansible utilise le langage YAML pour la plupart des données. YAML est un langage de sérialisation. Il est plus facile à lire et écrire que le JSON, et beaucoup moins verbeux que le XML.

YAML permet de manipuler quelques types de données :

Listes

Les éléments d’une liste sont précédés du caractère - :

beatles:
  - john
  - paul
  - george
  - ringo

La syntaxe suivante est moins utilisée mais équivalente : `:`

beatles: [ john, paul, george, ringo ]

Dictionnaires

Les dictionnaires sont des couples clé/valeur, séparées par le caractère :

instruments:
  john: piano
  paul: basse
  george: guitare
  ringo: batterie

La syntaxe suivante est également possible :

instruments: { john: piano, paul: basse }

Trucs et astuces

L'indentation lors de l'imbrication d’éléments est structurante. L'utilisation des espaces est obligatoire (les tabulations ne sont pas supportées).

Les chaînes de caractères ne nécessitent pas de formatage particulier, sauf en cas d’ambiguïté. Dans ce cas les chaînes sont entourées de caractères “ (double quote) :

# Invalide
message: error: blablabla
text: {{ hello world }}
 
# Valide
message: "error: blablabla"
text: "{{ hello world }}"

Définir les tâches (tasks)

Chaque tâche définie dans un playbook fait appel à un unique module Ansible. Une tâche est un dictionnaire qui comporte au minimum ces couples de clés/valeurs :

Des attributs additionnels peuvent être rencontrés, parmi lesquels :

Notifications et handlers

La section handlers permet de définir des tâches qui ne seront exécutées que sur notification (mot clé notify d'une tâche). Les handlers possèdent un nom et un appel à un module. Les handlers ne sont appelés qu'une fois toutes les tâches réalisées (et dans leur ordre d'apparition, et non pas dans l'ordre des notifications).

L'exemple suivant décrit comment redémarrer le service apache2 lorsque sa configuration a changé :

- hosts: webservers
  tasks:
  - name: Configure apache
    template:
      src: httpd.conf
      dest: /etc/httpd/conf.d/httpd.conf
    when: ansible_os_family == 'RedHat'
  notify: Restart apache
 
  handlers:
  - name: Restart apache
    service:
      name: httpd
      state: restarted

Le notify peut être une liste :

- hosts: localhost
  become: no
  tasks:
  - name: Action qui fait une modif 1
    file:
      path: /tmp/toto1
      state: touch
      mode: 0644
    notify:
    - Handler 1
    - Handler 2

Attention:

L'argument de notify et le nom du handler doivent être rigoureusement identiques.

Structures de contrôle

Les facts

La première action effectuée par Ansible lors de l’exécution d'un playbook est la récupération des facts de chacun des hôtes (via le module setup).

Cette action permet d’obtenir des variables (préfixées par ansible_) utilisables dans les filtres, tests et boucles du playbook.

Des variables liées à l’inventaire sont aussi disponibles :

Note:

On peut désactiver la récupération des facts dans un playbook en utilisant la directive gather_facts:no.

Il est possible de définir ses propres facts sur une machine.

Cela se fait en les déclarant dans un fichier /etc/ansible/facts.d/mon_fact.fact

Les facts sont définis au format JSON ou INI, ou peuvent être un exécutable qui retourne du JSON.

Les conditions

Certaines tâches du playbook peuvent ne pas toujours devoir être exécutées. La directive when permet de définir un test à effectuer. Si celui-ci retourne false, la tâche n’est pas exécutée.

Exemple d'utilisation de when pour gérer des distributions Linux différentes :

- name: Installing apache (Debian/Ubuntu)
  apt:
    name: apache2
    state: present
  when: ansible_os_family == 'Debian'
 
- name: Installing apache (RHEL)
  yum:
    name: httpd
    state: present
  when: ansible_os_family == 'RedHat'

Depuis la version 2.0 d’Ansible, les conditions peuvent s’appliquer à des blocs entiers :

- block:
  - debug: msg="Step 1"
  - debug: msg="Step 2"
  - debug: msg="Step 3"
  when: ansible_os_family == 'RedHat'

Les boucles

Les boucles permettent d'itérer sur les variables de type liste et dictionnaire. Cette technique permet d'exécuter plusieurs fois la même action sur un nombre d'éléments indéfini lors de l'écriture du rôle ou playbook.

La liste complète des boucles est disponible sur la documentation Ansible.

Les exemples suivants illustrent les boucles les plus utilisées.

with_items

Le mot clé with_items permet de boucler sur une liste. A chaque itération une variable item prend la valeur suivante de la liste.

- name: Installing editors packages
  apt:
    name: "{{ item }}"   
    with_items:
      - vim
      - emacs
      - nano

with_dict

Le mot clé with_dict permet de boucler sur un dictionnaire. A chaque itération la variable item définit deux attributs : key et value :

- name: Creating users
  user:
    name: "{{ item.key }}"
    uid: "{{ item.value }}"
  with_dict:
    user1: 1000
    user2: 1001
    user3: 1002

Utilisation des inclusions

La directive include permet d'importer une liste de tâches ou de handlers. Cette technique permet de rendre génériques certaines actions.

- hosts: all
  tasks:
  - include: common-setup.yml
  - name: something else
  ...

Il est possible de définir des variables au moment de l'inclusion d’un fichier :

- include: dns-master.yml domain=foo.com
- include: dns-master.yml domain=bar.net

Templates (Jinja2)

Ansible offre un module template permettant la création/modification de fichiers sur les hôtes via un langage de template (Jinja2).

Les templates peuvent utiliser les variables de l’inventaire et des playbooks, et offrent des structures de contrôles telles que les tests et les boucles.

Utilisation du module

Les paramètres src et dest sont les seuls obligatoires. Définir le propriétaire, le groupe et les droits associés au fichier à créer ou modifier est vivement recommandé.

Il est possible de créer une sauvegarde du fichier existant avant modification grâce au paramètre backup.

Exemple d'utilisation :

- template:
   src: /templates/appli.conf.j2
   dest: /etc/appli/appli.conf
   owner: root
   group: appli
   mode: 0640
   backup: yes

Syntaxe de base d’une template

Dans sa forme la plus simple, une template contient les données finales du fichier à installer sur l’hôte distant. Le même résultat peut être obtenu avec le module copy.

Le premier intérêt du module template est la possibilité d’utiliser des variables. Les variables utilisent le format {{ NOM_VARIABLE }}.

Exemple d’utilisation de variables dans une template :

$db_name = {{ db.name }};
$db_user = {{ db.user }};
$db_password = {{ db.password }};
$db_host = {{ db.host }};

Les filtres utilisables dans les playbooks sont valides dans les templates (voir la section Filtres).

Structures de contrôle

Les structures de contrôle Jinja permettent d’inclure un minimum d’intelligence dans les templates.

Les structures de contrôle sont définies dans des blocs. Les débuts et fins de blocs sont délimités par les caractères {% et %}, et contiennent le type de traitement à effectuer.

Tests

Les blocs if, elif, else et endif permettent d’appliquer des tests.

Exemple :

zone "{{ dns.domain }}" {
   {% if dns.type == 'master' %}
   type master;
   {% else %}
   type slave;
   masters {{ dns.masters | join(";") }};
   {% endif %}
 
   file "db.{{ dns.domain }}";
};

Boucles

Il est possible de boucler sur les listes, avec une syntaxe similaire à celle du langage python :

<ul>
{% for fruit in fruits %}
   <li>{{ fruit }}</li>
{% endfor %}
</ul>

Il en va de même pour boucler sur les éléments d’un dictionnaire :

<dl>
{% for name, inst in beatles.items() %}
   <dt>{{ name }}</dt>
   <dd>{{ inst }}</dd>
{% endfor %}
</dl>

Documentation complète

L’ensemble des fonctionnalités de Jinja2 est disponible sur la documentation en ligne.

Bonnes pratiques, Tips

Priorité des variables

Beaucoup de gens peuvent demander comment des variables en remplacent une autre. En fin de compte, la philosophie d’Ansible est qu’il est préférable de savoir où placer une variable.

Évitez de définir la variable «x» à 47 endroits et posez ensuite la question «quel x est utilisé». Pourquoi ? Parce que ce n’est pas la philosophie d’Ansible de faire les choses.

Trouvez où définir une variable sans compliquer les choses.

Voici l'ordre de priorité du plus petit au plus grand (les dernières variables répertoriées seront considérées comme prioritaires):

Debugguer son playbook

Quelques conseils pour pouvoir plus facilement débugguer ses playbooks :

$ ansible-playbook --syntax-check ...
$ ansible-playbook --check ...

Bien organiser son inventaire

En plus de la notion de groupes, on peut très bien utiliser des inventaires différents, avec des noms explicites, par exemple production, development.

Il suffira ensuite d’utiliser la commande :

$ ansible-playbook -i production mon_playbook.yml

Utiliser les tags

Ne pas hésiter à définir des tags qui permettent de sélectionner (--tags) ou d’exclure (--skip-tag) un sous-ensemble des tâches.

OS hétérogènes

Dans le cas d’un environnement avec des OS hétérogènes, on peut utiliser les facts pour savoir sur quel type d’OS on s'éxécute (when), et on peut inclure des fichiers de variables (ou templates, tasks, etc.) en fonction de ce critère. Exemple :

- name: Récupération des variables propres au système.
  include_vars: "{{ ansible_os_family }}.yml"
 
- include: setup-RedHat.yml
  when: ansible_os_family == 'RedHat'
 
- include: setup-Debian.yml
  when: ansible_os_family == 'Debian'

Plusieurs includes

Numéroter ses fichiers inclus pour connaître leur ordre d’apparition sans avoir à consulter le playbook :

- include: 01_install.yml
- include: 02_config.yml

Commandes et Shell

Les modules command et shell, bien que pratiques quand un module n'existe pas pour effectuer certaines actions, doivent être utilisés avec parcimonie, et il convient de s'assurer que leur utilisation sera idempotente (via par exemple l'utilisation des arguments creates ou removes).

Faire référence à la machine en cours de traitement

ansible_hostname permet d’utiliser le nom renvoyé par la machine (fact).

inventory_hostname permet d’utiliser le nom utilisé via ansible. (inventory_hostname_short permet de l’avoir sous sa forme courte, non fqdn).

play_hosts permet de récupérer la liste des machines sur lesquelles on est en train d’exécuter notre playbook.

- debug: msg="Execution sur {{ ansible_hostname }}
- debug: msg="Execution sur {{ inventory_hostname }}
- debug: msg="Execution planifie sur {{ item }}"
  with_items: "{{ play_hosts }}"

Modules courants

Les modules présentés ici donnent un aperçu des éléments disponibles et de leur utilisation, mais ne constituent pas une liste exhaustive.

La liste complète des modules core et extra disponibles pour Ansible est accessible en ligne.

Utilitaires

debug

Ce module permet l’affichage de messages et variables :

- debug: msg="Démarrage de {{ foo }} sur {{ ansible_hostname }}
- debug: var=ma_variable

pause

Le module pause permet de mettre en attente l’exécution d’un playbook. Ce module offre deux possibilités pour interrompre la pause :

Attente de 10 secondes :

pause:
   seconds: 10

Prompt utilisateur :

pause:
   prompt: "Valider le démarrage du service X"

wait_for

Ce module permet de mettre l'exécution du playbook en pause, jusqu'à ce qu'une condition soit vérifiée. Les conditions peuvent être de plusieurs types :

- name: attente du port 80
  wait_for:
     port: 80
     delay: 10

Packaging

Ansible permet une gestion avancée des packages. Ci joint la liste supportée à l'url suivante : https://docs.ansible.com/ansible/latest/modules/list_of_packaging_modules.html

cpanm

Cpan permet l’installation de modules perl :

cpanm:
  name: LaTeXML

gem

Gem permet l’installation de dépendances ruby :

gem:
  name: vagrant
  version: 1.0
  state: present

npm

Npm permet l’installation de paquets node.js :

npm:
  name: postgresql
  state: present
  production: yes

pip

Pip permet l’installation de logiciels python :

pip:
  name: ansible
  state: present
  virtualenv: ~/venvs/tools

Gestion des fichiers

copy

copy permet de copier un fichier local (ou un répertoire de façon récursive) vers l'hôte distant :

copy:
  src: files/appli.conf
  dest: /etc/appli.conf
  owner: root
  group: admin
  mode: 0640

Note:

Pour des copies de très nombreux fichiers, il faudra plutôt se tourner vers le module synchronize (rsync) ou unarchive.

fetch

fetch exécute l’opération inverse de copy, il télécharge un fichier depuis un hôte distant. Si l’option flat n’est pas utilisée ce module crée un dossier du même nom que l’hôte, dans lequel l’arborescence complète du fichier source est recréée :

fetch:
  src: /var/log/syslog
  dest: fetched/

get_url

get_url permet de récupérer un fichier (ou un répertoire de façon récursive) au travers d’un serveur HTTP, HTTPS ou FTP.

On peut aussi forcer la récupération d'un fichier si la destination n'existe pas déjà.

get_url:
  url: http://example.com/path/file.conf
  dest: /etc/foo.conf
  sha256sum: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c

file

file permet de modifier les attributs d’un fichier (propriétaire, groupe…). Ce module permet également de créer des dossiers, liens symboliques, etc. :

- file:
    path: /etc/shadow
    owner: root
    group: root
    mode: 0400
 
- file:
    path: /etc/config_dir
    state: directory

lineinfile

linefile permet d'insérer/modifier/supprimer une ligne dans un fichier. L'option regexp permet de modifier facilement une ligne existante :

lineinfile:
  dest: /etc/apache2/ports.conf
  regexp: "^Listen"
  line: "Listen 8080"

Note:

Le module ini_file est mieux adapté pour gérer les fichiers au format INI.

stat

stat ne modifie rien mais récupère des informations sur l'état d’un fichier. Ce module permet par exemple de valider la présence d'un fichier pour déclencher des actions conditionnelles :

- stat:
    path: /etc/already-configured
  register: st
 
- include: configure.yml
  when: st.stat.exists == false

Gestion de sources

Les modules bzr, git et subversion permettent de cloner ou mettre à jour des dépôts de code.

Exemple d'utilisation :

- git:
    repo: https://github.com/ansible/ansible-modules-core.git
    dest: /usr/local/lib/ansible
    version: 1.8.4
  register: git_result
 
- shell: myscript.sh
  when: git_result|changed

Bases de données

MySQL

Plusieurs modules permettent d’administrer des serveurs MySQL :

PostgreSQL

Plusieurs modules permettent d’administrer des serveurs PostgreSQL :

Autres bases de données

Des modules additionnels permettent de gérer des bases de données NoSQL :

Cloud / Virtualisation

Ansible dispose de modules pour la gestion d’hyperviseurs et plateformes de cloud computing :

∙ Google

ANNEXE - préparation des serveurs

Auncune connection en tant que root. Nous allons créer un user de déléguation pour les connexion SSH avec les droits sudo qui lui autoriserons le tout (soit local/soit ldap)

# groupadd devops
# adduser --groups devops ansible
# su - ansible
# ssh-keygen -t rsa -b 4096 -C "Compte DevOPS"
# ssh-copy-id ansible@192.168.1.XXX

Valider la keys

# ssh ansible@192.168.1.XXX

Le moyen le plus efficace pour configurer l'utilisateur ansible afin qu'il puisse utiliser sudo sans être invité à entrer un mot de passe est de l'ajouter à la liste des sudoers comme suit:

# visudo -f /etc/sudoers.d/ansible

Tout ce qui se trouve dans le dossier /etc/sudoers.d/* est inclus dans les privilèges «sudoers» lorsqu’il est créé par l’utilisateur root. C’est pourquoi nous avons créé cela en tant qu’utilisateur root et dans ce dossier.

Avec ce fichier ouvert, ajoutez ceci au fichier, puis enregistrez-le.

# Add ansible user
ansible ALL=(ALL) NOPASSWD: ALL

URL

https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html