Ansible

De Justine's wiki
Aller à la navigation Aller à la recherche

Liens

https://learnxinyminutes.com/docs/ansible/ https://www.ansible.com/blog/using-ansible-to-manage-rhel-5-yesterday-today-and-tomorrow

Présentation

Ansible est une plateforme logicielle libre pour la configuration et la gestion des ordinateurs. Elle combine le déploiement de logiciels multi-nœuds, l'exécution des tâches ad-hoc, et la gestion de configuration. Elle gère les différents nœuds à travers SSH et ne nécessite l'installation d'aucun logiciel supplémentaire sur ceux-ci. Les modules communiquent via la sortie standard en notation JSON et peuvent être écrits dans n'importe quel langage de programmation. Le système utilise YAML pour exprimer des descriptions réutilisables de systèmes, appelés playbook. Elle permet :

  • D'automatiser : déployer des applications, gérer des systèmes
  • De gagner du temps : grâce aux playbooks, on peut résoudre les problèmes une fois et partager facilement la solution
  • De collaborer : en créant une "culture de l'automatisation"
  • D'intégrer plus facilement en automatisant les technologies que l'on utilise déjà.

Mise en place

Source :

https://www.tartarefr.eu/ansible-par-la-pratique-premiere-partie-les-bases/

J'utilise deux machines :

  • Mon PC sous Ubuntu 18.10, sur lequel j'installe Ansible et sshpass
  • Une VM Debian basique, qui sera ma cible (192.168.1.49)

Avant toute chose, il faut que notre VM soit dans les known_hosts de la machine Ansible. Il suffit de s'y connecter une fois en ssh pour ajouter la clef !

Je commence par installer Ansible sur mon PC. Ensuite, je peux commencer à lancer une commande via Ansible :

justine@Justine-pc:/etc/ansible$ ansible 192.168.1.49 -m ping

Mais ça ne fonctionne pas : Ansible ne connait pas la cible, et on a pas d'utilisateur sur celle-ci !

Dans mon dossier home, je créée deux répertoires : prod et preprod, et dans chacun d'entre eux je met un fichier hosts.ini vierge. Ce fichier contiendra notre inventaire de machines.

Ensuite, dans preprod/hosts.ini, je mets :

[server]
192.168.1.49

[ansible]
localhost

Je peux ensuite rééessayer en précisant le répertoire de notre environnement et un utilisateur et ça fonctionne :

justine@Justine-pc:~/Ansible$ ansible -i ~/Ansible/preprod/hosts.ini 192.168.1.49 --user user --ask-pass -m ping
SSH password:
192.168.1.49 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Je peux tenter une commande :

justine@Justine-pc:~/Ansible$ ansible -i ~/Ansible/preprod/hosts.ini 192.168.1.49 --user user --ask-pass -a whoami
SSH password:
192.168.1.49 | CHANGED | rc=0 >>
user

Par défaut, Ansible utilise le même utilisateur que l'utilisateur local sur l'hôte distant. C'est pour cela qu'il faut bien gérer les utilisateurs. De plus, il faut penser que la connexion root en ssh est désactivée par défaut sur Debian !

Lancer une série de commandes

Le fichier permettant de lister les commande à lancer s’appelle un playbook. Il peut être monolithique ou divisé en plusieurs parties. Ansible recommande la séparation par rôle, ce qui permet de réutiliser les commandes d’un playbook et de les partager facilement avec la communauté.

Les rôles

Il faut bien réfléchir à la séparation des rôles qu'aura notre serveur, afin de garder une bonne modularité. Si on prend l'exemple d'un serveur web personnel qui contiendrait un blog Wordpress, un outil d'analyse de trafic web Piwik et du monitoring, on a déjà 3 rôles. Mais chacun de ces rôles en nécéssite d'autres (bdd, serveur web...), et que la machine doit rester à jour, on arrive a un grand nombre de rôles :

  •     system: concernera la post-installation du système
    •         Mettre le système à jour
    •         Définition des pools ntp (fr)
    •         Définition du nom d’hôte
    •         Définition basique du firewall: SSH (22)
    •         Redirection des mails locaux vers une adresse externe
    •         etc…
  •     pki: Concernera l’obtention et la mise à jour des certificats SSL
    •         Copie de nos clés privées
    •         Copies de nos fichiers et scripts gérant la pki (systemd)
  •     webserver: Concernera l’installation et la configuration d’apache
    •         Installation et configuration d’apache
    •         Mise à jour des extensions (ex modsecurity), hors RPM (les paquets RPMs seront mis à jour avec le rôle system)
    •         Ajout des ports HTTP (80) et HTTPS (443) au firewall
  •     database: Concernera l’installation et la configuration de mariadb
    •         Installation et configuration de mariadb
  •     blog: Concernera l’installation et la configuration de wordpress
    •         Installation et configuration du blog
    •         définition de l’alias ou du vhost pour le webserver
    •         import de la sauvegarde si elle existe
    •         Mise à jour des extensions, hors RPM (les paquets RPMs seront mis à jour avec le rôle system)
  •     webstat: Concernera l’installation et la configuration de piwik
    •         Installation et configuration de piwik
    •         définition de l’alias ou du vhost pour le webserver
    •         import de la sauvegarde si elle existe
  •     monitoring: Concernera l’installation et la configuration du monitoring
    •         Installation et configuration des outils
  •     ids: Concernera l’installation et la configuration des outils de détection et de vérification d’intrusion
    •         Installation et configuration des outils

Du coup, le changement d'un rôle impactera pas ou peu les autres, et on pourra facilement changer certaines choses. Changer de blog n'impactera pas le reste par exemple, mais changer de serveur web impactera les autres rôles.

Les Playbooks

Il s'agit de fichiers au format YAML, qui contient une succession de tâche à accomplir. Par défaut, une erreur sur l'une d'entre elles entraîne l'arrêt du processus. Il existe beaucoup de modules différents et la doc les présente tous :

https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

À propos du YAML :

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

À propos des playbooks :

https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#playbook-language-example

 

J'ai créé un playbook tout simple qui se contente d'installer apache2 :

#site.yml
---
- hosts: server #Je choisis mon hôte
  tasks:
    - name: update installation de serveur web #Je nomme ma tâche
      apt:  #Différentes commandes apt
        name: apache2
        force_apt_get: yes #Sinon, il utilise aptitude
        update_cache: yes
      become: true #Sert à utiliser sudo

Que je peux ensuite lancer :

justine@Justine-pc:~/Ansible/preprod$ ansible-playbook -i ~/Ansible/preprod/hosts.ini --user user --ask-pass --ask-become-pass site.yml
SSH password:
SUDO password[defaults to SSH password]:

PLAY [server] ******************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************
ok: [192.168.1.49]

TASK [update installation de serveur web] **************************************************************************************************

changed: [192.168.1.49]

PLAY RECAP *********************************************************************************************************************************
192.168.1.49               : ok=2    changed=1    unreachable=0    failed=0

Ici :

  • ansible-playbook -i ~/Ansible/preprod/hosts.ini : J'utilise un playbook en précisant l'environnement
  • --user user --ask-pass : utilisateur et demande de mot de passe pour ssh
  • --ask-become-pass : mot de passe pour sudo
  • site.yml : mon playbook

Si je relance le playbook, les tâches déjà effectuées seront ingorées. Cela évite les effets de bord : Les playbooks sont idempotents, c'est-à-dire qu'on peut bien les réutiliser si on veut ! Ici, je pourrais rajouter des fonctions à mon playbook et le relancer si j'en ai envie.



Chiffrer les variables des playbooks

Les playbooks peuvent s'avérer dangereux au niveau sécurité : si je dois donner un mot de passe à un utilisateur via un playbook, je ne vais pas par la suite le commit tel quel sur un dépôt public par la suite ! Pour ça, Ansible-vault propose deux façon de chiffrer les fichiers de variables :

  • Chiffrer tout le fichier de variables et utiliser les commandes ad-hoc pour éditer le fichier
  • Chiffrer seulement la valeur de la variable dans un fichier texte en clair

Chiffrer tout le fichier

On créée notre fichier chiffré et on inscrit notre variable une fois le fichier ouvert par l'éditeur par défaut (variable EDITOR) avec la commande :

justine@Justine-pc:~/Ansible/preprod$ ansible-vault create undossier/unfichierdevariables

#Je peux ensuite l'éditer :

justine@Justine-pc:~/Ansible/preprod$ ansible-vault edit undossier/unfichierdevariables

On peut aussi créer un fichier en clair et le chiffrer après :

echo 'mysql_root_password = "monsupermotdepasse"' > host_vars/server
ansible-vault encrypt host_vars/server

Chiffrer la valeur de la variable

On chiffre la valeur :

ansible-vault encrypt_string --vault-id @prompt 'monsupermotdepasse' --name 'mysql_root_password' >> host_vars/server
New vault password (default):
Confirm vew vault password (default):
Encryption successful

Mais je n'ai pas trop compris ce point-là...

Un playbook plus abouti

Le playbook suivant donne une idée un peu complète des possibilités offertes par l'outil, et devrait parler de lui-même.

Fichier de variables

---
name: johndoe
#pubkey est un lien vers un git de type https://mongit.fr/user.keys
#Il faut bien sûr avoir au préalable injecté une clef dans le git en question
pubkey: https://monsuperlien.com/johndoe.keys
file: /home/justine/Nextcloud/Ansible/resultat.txt
inventoryfile: /home/justine/Nextcloud/Ansible/inventaire.txt

Fichier hosts

[serv]
serv.innertech.ovh

Playbook

---
- hosts: nest
  tasks:
    - name: Dis bonjour
      debug:
        msg: "Hi, I will be adding a user named {{ name }} and inject his key from {{ pubkey }}"
        msg: "After that, the user {{ name }} shall be able to sudo without a passwd (as he won't have any)"

    - name: Creation de l'utilisateur
      user:
        name: "{{ name }}"
        shell: /bin/bash
        groups: sudo
        append: yes
      become: yes

    - name: Ajout de sudo NOPASSWD
      copy: 
        content: '%sudo ALL=(ALL:ALL) NOPASSWD:ALL'
        dest: /etc/sudoers.d/sudo_nopasswd
        mode: 0440
      become: yes

    - name: Injection de la clef publique
      authorized_key:
        user: "{{ name }}"
        state: present
        key: "{{ pubkey }}"
      become: yes 

    - name: Informations sur Lynis
      debug:
        msg: "Next, we will try to install Lynis and run it"

    - name: Installation de Lynis
      apt:
        name: lynis
        force_apt_get: yes
        update_cache: yes
      become: yes

    - name: Lancement de Lynis et renvoi du resultat
      shell: lynis --no-colors audit system 
      register: resultat
      args: 
        executable: /bin/bash
      become: yes

    - name: Enregistrement du resultat de Lynis 
      local_action: 
        module: copy
        content: "{{ resultat }}"
        dest: "{{ file }}"

    - name: Recuperation d'informations
      setup:
        filter: ansible_default_ipv4.address

    - name: ajout de la machine à un fichier d'inventaire
      local_action:
        module: copy
        content: "{{ ansible_default_ipv4.address }} User: {{ name }} Pub_Key: {{ pubkey }}"
        dest: "{{ inventoryfile }}"

Un role entier

À partir du playbook vu au-dessus, je peux l'améliorer et en faire un rôle. Mon rôle est plus complet et est une base pour n'importe quelle machine.

Je commence par initialiser mon rôle. C'est assez similaire à git sur ce point-là :

ansible-galaxy init monrole

Je récupère un dossier contenant tous les dossiers et fichiers de base dont j'ai besoin :

  • defaults : variable par défaut
  • files : fichier à envoyer avec le playbook
  • handlers : les handlers
  • meta
  • README.md : idem à git
  • tasks : Contient le "gros" du travail, c'est-à-dire les tâches à effectuer
  • templates
  • vars: mes variables par machine.

Dans chacun de ces dossiers se trouve un main.yml. Ces fichiers sont exécutés automatiquement et doivent contenir tout notre travail.

Détail du role hello.base

Je vais résumer ici mon role hello.base, qui est une installation de base de mes machines, sauf files (qui contient un fichier de conf de fail2ban et une commande cron pour la synchro ntp):

defaults/main.yml:

---
name: johndoe
#pubkey est un lien vers un git de type https://mongit.fr/user.keys
#Il faut bien sûr avoir au préalable injecté une clef dans le git en question
pubkey: https://book.innertech.ovh/johndoe.keys
file: /home/justine/Nextcloud/Ansible/resultat.txt
inventoryfile: /home/justine/Nextcloud/Ansible/inventaire.txt
ports: 22/tcp

tasks/main.yml:


---
# tasks file for hello.base
- name: Dis bonjour
  debug:
    msg: "Hi, I will be adding a user named {{ name }} and inject his key from {{ pubkey }}"
    msg: "After that, the user {{ name }} shall be able to sudo without a passwd (as he won't have any)"

- name: Creation de l'utilisateur
  user:
    name: "{{ name }}"
    shell: /bin/bash
    groups: sudo
    append: yes
  become: yes

- name: Ajout de sudo NOPASSWD
  copy: 
    content: '%sudo ALL=(ALL:ALL) NOPASSWD:ALL'
    dest: /etc/sudoers.d/sudo_nopasswd
    mode: 0440
  become: yes

- name: Injection de la clef publique
  authorized_key:
    user: "{{ name }}"
    state: present
    key: "{{ pubkey }}"
  become: yes 

- name: Informations sur Lynis
  debug:
    msg: "Next, we will try to install Lynis and run it"

- name: Installation de Lynis
  apt:
    name: lynis
    force_apt_get: yes
    update_cache: yes
  become: yes

- name: Lancement de Lynis et renvoi du resultat
  shell: lynis --no-colors audit system 
  register: resultat
  args: 
    executable: /bin/bash
  become: yes

- name: Enregistrement du resultat de Lynis 
  local_action: 
    module: copy
    content: "{{ resultat }}"
    dest: "{{ file }}"

- name: Informations sécurité
  debug:
    msg: "We will then proceed to secure the system"

- name: Installation de UFW
  apt:
    name: ufw
    force_apt_get: yes
    update_cache: no
  become: yes

- name: Mise en place de NTP
  apt:
    name: ntpdate
    force_apt_get: yes
    update_cache: no

- name: Copie des fichiers
  copy: 
    src: files/cron.ntpdate
    dest: /etc/cron.d/cron.ntpdate
    owner: root
    group: root
    mode: 0644
  become: yes

- name: ouverture des ports
  shell: ufw allow {{ ports }} 
  become: yes

- name: Sauvegarde de la configuration ufw
  shell: ufw reload
  become: yes
         
- name: Recuperation d'informations
  setup:
    filter: ansible_default_ipv4.address

- name: Installation outils de sécurité
  apt:
    name: "{{ packages }}"
    force_apt_get: yes
  vars:
    packages:
      - fail2ban
      - clamav
      - logrotate
  become: yes

- name: Configuration de fail2ban
  copy: 
    src: files/jail.conf
    dest: /etc/fail2ban/jail.conf
    owner: root
    group: root
    mode: 0644
    force: yes

- name: redémarrage de fail2ban
  shell: systemctl restart fail2ban
  become: yes

- name: ajout de la machine à un fichier d'inventaire
  local_action:
    module: copy
    content: "{{ ansible_default_ipv4.address }} User: {{ name }} Pub_Key: {{ pubkey }}"
    dest: "{{ inventoryfile }}"

Utiliser ce rôle dans un playbook

Maintenant que j'ai créé mon rôle, je vais pouvoir l'utiliser dans le cadre de mes playbooks. Pour cela, c'est assez simple. Voici un playbook d'exemple :

---
- hosts: ancible
  become: yes
  roles:
    - roles/hello.base

Son dossier contient :

  • Un fichier hosts
  • le playbook en lui-même
  • un dossier roles contenant mon hello.base

Il suffit ensuite de lancer mon playbook pour voir le rôle s'exécuter. Bien évidemment, je pourrais avoir besoin de modifier les variable de mon rôle.

Quelles sont les variables qu'Ansible récupère sur les hôtes ?

Lors d'un gather facts normal, ansible récupère des variables sur les cibles. Pour les voir :

ansible -m setup hostname

Ce qui donne:

scdev | success >> {
    "ansible_facts": {                                                                                                 
        "ansible_all_ipv4_addresses": [                                                                                
            "10.0.2.15",                                                                                               
            "192.168.10.10"                                                                                            
        ],                                                                                                             
        "ansible_all_ipv6_addresses": [                                                                                
            "fe80::a00:27ff:fe12:9698",                                                                                
            "fe80::a00:27ff:fe74:1330"                                                                                 
        ],                                                                                                             
        "ansible_architecture": "i386",                                                                                
        "ansible_bios_date": "12/01/2006",                                                                             
        "ansible_bios_version": "VirtualBox",                                                                          
        "ansible_cmdline": {                                                                                           
            "BOOT_IMAGE": "/vmlinuz-3.2.0-23-generic-pae",                                                             
            "quiet": true,                                                                                             
            "ro": true,                                                                                                
            "root": "/dev/mapper/precise32-root"                                                                       
        },                                                                                                             
        "ansible_date_time": {                                                                                         
            "date": "2013-09-17",                                                                                      
            "day": "17",                                                                                               
            "epoch": "1379378304",                                                                                     
            "hour": "00",                                                                                              
            "iso8601": "2013-09-17T00:38:24Z",                                                                         
            "iso8601_micro": "2013-09-17T00:38:24.425092Z",                                                            
            "minute": "38",                                                                                            
            "month": "09",                                                                                             
            "second": "24",                                                                                            
            "time": "00:38:24",                                                                                        
            "tz": "UTC",                                                                                               
            "year": "2013"                                                                                             
        },                                                                                                             
        "ansible_default_ipv4": {                                                                                      
            "address": "10.0.2.15",                                                                                    
            "alias": "eth0",                                                                                           
            "gateway": "10.0.2.2",                                                                                     
            "interface": "eth0",                                                                                       
            "macaddress": "08:00:27:12:96:98",                                                                         
            "mtu": 1500,                                                                                               
            "netmask": "255.255.255.0",                                                                                
            "network": "10.0.2.0",                                                                                     
            "type": "ether"                                                                                            
        },                                                                                                             
        "ansible_default_ipv6": {},                                                                                    
        "ansible_devices": {                                                                                           
            "sda": {                                                                                                   
                "holders": [],                                                                                         
                "host": "SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)",                                                                                                                
                "model": "VBOX HARDDISK",                                                                              
                "partitions": {                                                                                        
                    "sda1": {                                                                                          
                        "sectors": "497664",                                                                           
                        "sectorsize": 512,                                                                             
                        "size": "243.00 MB",                                                                           
                        "start": "2048"                                                                                
                    },                                                                                                 
                    "sda2": {                                                                                          
                        "sectors": "2",                                                                                
                        "sectorsize": 512,                                                                             
                        "size": "1.00 KB",                                                                             
                        "start": "501758"                                                                              
                    },                                                                                                 
                },                                                                                                     
                "removable": "0",                                                                                      
                "rotational": "1",                                                                                     
                "scheduler_mode": "cfq",                                                                               
                "sectors": "167772160",                                                                                
                "sectorsize": "512",                                                                                   
                "size": "80.00 GB",                                                                                    
                "support_discard": "0",                                                                                
                "vendor": "ATA"                                                                                        
            },                                                                                                         
            "sr0": {                                                                                                   
                "holders": [],                                                                                         
                "host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",                           
                "model": "CD-ROM",                                                                                     
                "partitions": {},                                                                                      
                "removable": "1",                                                                                      
                "rotational": "1",                                                                                     
                "scheduler_mode": "cfq",                                                                               
                "sectors": "2097151",                                                                                  
                "sectorsize": "512",                                                                                   
                "size": "1024.00 MB",                                                                                  
                "support_discard": "0",                                                                                
                "vendor": "VBOX"                                                                                       
            },                                                                                                         
            "sr1": {                                                                                                   
                "holders": [],                                                                                         
                "host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",                           
                "model": "CD-ROM",                                                                                     
                "partitions": {},                                                                                      
                "removable": "1",                                                                                      
                "rotational": "1",                                                                                     
                "scheduler_mode": "cfq",                                                                               
                "sectors": "2097151",                                                                                  
                "sectorsize": "512",                                                                                   
                "size": "1024.00 MB",                                                                                  
                "support_discard": "0",                                                                                
                "vendor": "VBOX"                                                                                       
            }                                                                                                          
        },                                                                                                             
        "ansible_distribution": "Ubuntu",                                                                              
        "ansible_distribution_release": "precise",                                                                     
        "ansible_distribution_version": "12.04",                                                                       
        "ansible_domain": "",                                                                                          
        "ansible_eth0": {                                                                                              
            "active": true,                                                                                            
            "device": "eth0",                                                                                          
            "ipv4": {                                                                                                  
                "address": "10.0.2.15",                                                                                
                "netmask": "255.255.255.0",                                                                            
                "network": "10.0.2.0"                                                                                  
            },                                                                                                         
            "ipv6": [                                                                                                  
                {                                                                                                      
                    "address": "fe80::a00:27ff:fe12:9698",                                                             
                    "prefix": "64",                                                                                    
                    "scope": "link"                                                                                    
                }                                                                                                      
            ],                                                                                                         
            "macaddress": "08:00:27:12:96:98",                                                                         
            "module": "e1000",                                                                                         
            "mtu": 1500,                                                                                               
            "type": "ether"                                                                                            
        },                                                                                                             
        "ansible_eth1": {                                                                                              
            "active": true,                                                                                            
            "device": "eth1",                                                                                          
            "ipv4": {                                                                                                  
                "address": "192.168.10.10",                                                                            
                "netmask": "255.255.255.0",                                                                            
                "network": "192.168.10.0"                                                                              
            },                                                                                                         
            "ipv6": [                                                                                                  
                {                                                                                                      
                    "address": "fe80::a00:27ff:fe74:1330",                                                             
                    "prefix": "64",                                                                                    
                    "scope": "link"                                                                                    
                }                                                                                                      
            ],                                                                                                         
            "macaddress": "08:00:27:74:13:30",                                                                         
            "module": "e1000",                                                                                         
            "mtu": 1500,                                                                                               
            "type": "ether"                                                                                            
        },                                                                                                             
        "ansible_form_factor": "Other",                                                                                
        "ansible_fqdn": "scdev",                                                                                       
        "ansible_hostname": "scdev",                                                                                   
        "ansible_interfaces": [                                                                                        
            "lo",                                                                                                      
            "eth1",                                                                                                    
            "eth0"                                                                                                     
        ],                                                                                                             
        "ansible_kernel": "3.2.0-23-generic-pae",                                                                      
        "ansible_lo": {                                                                                                
            "active": true,                                                                                            
            "device": "lo",                                                                                            
            "ipv4": {                                                                                                  
                "address": "127.0.0.1",                                                                                
                "netmask": "255.0.0.0",                                                                                
                "network": "127.0.0.0"                                                                                 
            },                                                                                                         
            "ipv6": [                                                                                                  
                {                                                                                                      
                    "address": "::1",                                                                                  
                    "prefix": "128",                                                                                   
                    "scope": "host"                                                                                    
                }                                                                                                      
            ],                                                                                                         
            "mtu": 16436,                                                                                              
            "type": "loopback"                                                                                         
        },                                                                                                             
        "ansible_lsb": {                                                                                               
            "codename": "precise",                                                                                     
            "description": "Ubuntu 12.04 LTS",                                                                         
            "id": "Ubuntu",                                                                                            
            "major_release": "12",                                                                                     
            "release": "12.04"                                                                                         
        },                                                                                                             
        "ansible_machine": "i686",                                                                                     
        "ansible_memfree_mb": 23,                                                                                      
        "ansible_memtotal_mb": 369,                                                                                    
        "ansible_mounts": [                                                                                            
            {                                                                                                          
                "device": "/dev/mapper/precise32-root",                                                                
                "fstype": "ext4",                                                                                      
                "mount": "/",                                                                                          
                "options": "rw,errors=remount-ro",                                                                     
                "size_available": 77685088256,                                                                         
                "size_total": 84696281088                                                                              
            },                                                                                                         
            {                                                                                                          
                "device": "/dev/sda1",                                                                                 
                "fstype": "ext2",                                                                                      
                "mount": "/boot",                                                                                      
                "options": "rw",                                                                                       
                "size_available": 201044992,                                                                           
                "size_total": 238787584                                                                                
            },                                                                                                         
            {                                                                                                          
                "device": "/vagrant",                                                                                  
                "fstype": "vboxsf",                                                                                    
                "mount": "/vagrant",                                                                                   
                "options": "uid=1000,gid=1000,rw",                                                                     
                "size_available": 42013151232,                                                                         
                "size_total": 484145360896                                                                             
            }                                                                                                          
        ],                                                                                                             
        "ansible_os_family": "Debian",                                                                                 
        "ansible_pkg_mgr": "apt",                                                                                      
        "ansible_processor": [                                                                                         
            "Pentium(R) Dual-Core  CPU      E5300  @ 2.60GHz"                                                          
        ],                                                                                                             
        "ansible_processor_cores": "NA",                                                                               
        "ansible_processor_count": 1,                                                                                  
        "ansible_product_name": "VirtualBox",                                                                          
        "ansible_product_serial": "NA",                                                                                
        "ansible_product_uuid": "NA",                                                                                  
        "ansible_product_version": "1.2",                                                                              
        "ansible_python_version": "2.7.3", 
        "ansible_selinux": false, 
        "ansible_swapfree_mb": 766, 
        "ansible_swaptotal_mb": 767, 
        "ansible_system": "Linux", 
        "ansible_system_vendor": "innotek GmbH", 
        "ansible_user_id": "neves", 
        "ansible_userspace_architecture": "i386", 
        "ansible_userspace_bits": "32", 
        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "virtualbox"
    }, 
    "changed": false
}

Un autre exemple

ansible -m setup 192.168.1.3 --ask-pass --ask-become-pass -i invent -u justine

############Donne
192.168.1.3 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.1.3"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::dc0f:6bff:feef:3c09"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "04/01/2014", 
        "ansible_bios_version": "rel-1.11.1-0-g0551a4be2c-prebuilt.qemu-project.org", 
        "ansible_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-4.9.0-8-amd64", 
            "quiet": true, 
            "ro": true, 
            "root": "UUID=e3ec661d-def0-4549-9627-ba6ddf0d15ab"
        }, 
        "ansible_date_time": {
            "date": "2019-07-18", 
            "day": "18", 
            "epoch": "1563457682", 
            "hour": "15", 
            "iso8601": "2019-07-18T13:48:02Z", 
            "iso8601_basic": "20190718T154802247424", 
            "iso8601_basic_short": "20190718T154802", 
            "iso8601_micro": "2019-07-18T13:48:02.247572Z", 
            "minute": "48", 
            "month": "07", 
            "second": "02", 
            "time": "15:48:02", 
            "tz": "CEST", 
            "tz_offset": "+0200", 
            "weekday": "jeudi", 
            "weekday_number": "4", 
            "weeknumber": "28", 
            "year": "2019"
        }, 
        "ansible_default_ipv4": {
            "address": "192.168.1.3", 
            "alias": "ens18", 
            "broadcast": "192.168.1.255", 
            "gateway": "192.168.1.254", 
            "interface": "ens18", 
            "macaddress": "de:0f:6b:ef:3c:09", 
            "mtu": 1500, 
            "netmask": "255.255.255.0", 
            "network": "192.168.1.0", 
            "type": "ether"
        }, 
        "ansible_default_ipv6": {}, 
        "ansible_device_links": {
            "ids": {
                "sda": [
                    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
                ], 
                "sda1": [
                    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part1"
                ], 
                "sda2": [
                    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part2"
                ], 
                "sda5": [
                    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part5"
                ], 
                "sr0": [
                    "ata-QEMU_DVD-ROM_QM00003"
                ]
            }, 
            "labels": {
                "sr0": [
                    "Debian\\x209.8.0\\x20amd64\\x20n"
                ]
            }, 
            "masters": {}, 
            "uuids": {
                "sda1": [
                    "e3ec661d-def0-4549-9627-ba6ddf0d15ab"
                ], 
                "sda5": [
                    "b914f733-6b22-42b9-b9c1-886651230752"
                ], 
                "sr0": [
                    "2019-02-16-12-00-40-00"
                ]
            }
        }, 
        "ansible_devices": {
            "sda": {
                "holders": [], 
                "host": "SCSI storage controller: Red Hat, Inc Virtio SCSI", 
                "links": {
                    "ids": [
                        "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
                    ], 
                    "labels": [], 
                    "masters": [], 
                    "uuids": []
                }, 
                "model": "QEMU HARDDISK", 
                "partitions": {
                    "sda1": {
                        "holders": [], 
                        "links": {
                            "ids": [
                                "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part1"
                            ], 
                            "labels": [], 
                            "masters": [], 
                            "uuids": [
                                "e3ec661d-def0-4549-9627-ba6ddf0d15ab"
                            ]
                        }, 
                        "sectors": "123729920", 
                        "sectorsize": 512, 
                        "size": "59.00 GB", 
                        "start": "2048", 
                        "uuid": "e3ec661d-def0-4549-9627-ba6ddf0d15ab"
                    }, 
                    "sda2": {
                        "holders": [], 
                        "links": {
                            "ids": [
                                "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part2"
                            ], 
                            "labels": [], 
                            "masters": [], 
                            "uuids": []
                        }, 
                        "sectors": "2", 
                        "sectorsize": 512, 
                        "size": "1.00 KB", 
                        "start": "123734014", 
                        "uuid": null
                    }, 
                    "sda5": {
                        "holders": [], 
                        "links": {
                            "ids": [
                                "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part5"
                            ], 
                            "labels": [], 
                            "masters": [], 
                            "uuids": [
                                "b914f733-6b22-42b9-b9c1-886651230752"
                            ]
                        }, 
                        "sectors": "2093056", 
                        "sectorsize": 512, 
                        "size": "1022.00 MB", 
                        "start": "123734016", 
                        "uuid": "b914f733-6b22-42b9-b9c1-886651230752"
                    }
                }, 
                "removable": "0", 
                "rotational": "1", 
                "sas_address": null, 
                "sas_device_handle": null, 
                "scheduler_mode": "cfq", 
                "sectors": "125829120", 
                "sectorsize": "512", 
                "size": "60.00 GB", 
                "support_discard": "4096", 
                "vendor": "QEMU", 
                "virtual": 1
            }, 
            "sr0": {
                "holders": [], 
                "host": "IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]", 
                "links": {
                    "ids": [
                        "ata-QEMU_DVD-ROM_QM00003"
                    ], 
                    "labels": [
                        "Debian\\x209.8.0\\x20amd64\\x20n"
                    ], 
                    "masters": [], 
                    "uuids": [
                        "2019-02-16-12-00-40-00"
                    ]
                }, 
                "model": "QEMU DVD-ROM", 
                "partitions": {}, 
                "removable": "1", 
                "rotational": "1", 
                "sas_address": null, 
                "sas_device_handle": null, 
                "scheduler_mode": "cfq", 
                "sectors": "598016", 
                "sectorsize": "2048", 
                "size": "292.00 MB", 
                "support_discard": "0", 
                "vendor": "QEMU", 
                "virtual": 1
            }
        }, 
        "ansible_distribution": "Debian", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/os-release", 
        "ansible_distribution_file_variety": "Debian", 
        "ansible_distribution_major_version": "9", 
        "ansible_distribution_release": "stretch", 
        "ansible_distribution_version": "9", 
        "ansible_dns": {
            "nameservers": [
                "193.51.100.100", 
                "1.1.1.1"
            ], 
            "search": [
                "u-pec.fr"
            ]
        }, 
        "ansible_domain": "u-pec.fr", 
        "ansible_effective_group_id": 1000, 
        "ansible_effective_user_id": 1000, 
        "ansible_ens18": {
            "active": true, 
            "device": "ens18", 
            "features": {
                "busy_poll": "off [fixed]", 
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "on", 
                "highdma": "off [fixed]", 
                "hw_tc_offload": "off [fixed]", 
                "l2_fwd_offload": "off [fixed]", 
                "large_receive_offload": "off [fixed]", 
                "loopback": "off [fixed]", 
                "netns_local": "off [fixed]", 
                "ntuple_filters": "off [fixed]", 
                "receive_hashing": "off [fixed]", 
                "rx_all": "off", 
                "rx_checksumming": "off", 
                "rx_fcs": "off", 
                "rx_vlan_filter": "on [fixed]", 
                "rx_vlan_offload": "on", 
                "rx_vlan_stag_filter": "off [fixed]", 
                "rx_vlan_stag_hw_parse": "off [fixed]", 
                "scatter_gather": "on", 
                "tcp_segmentation_offload": "on", 
                "tx_checksum_fcoe_crc": "off [fixed]", 
                "tx_checksum_ip_generic": "on", 
                "tx_checksum_ipv4": "off [fixed]", 
                "tx_checksum_ipv6": "off [fixed]", 
                "tx_checksum_sctp": "off [fixed]", 
                "tx_checksumming": "on", 
                "tx_fcoe_segmentation": "off [fixed]", 
                "tx_gre_csum_segmentation": "off [fixed]", 
                "tx_gre_segmentation": "off [fixed]", 
                "tx_gso_partial": "off [fixed]", 
                "tx_gso_robust": "off [fixed]", 
                "tx_ipxip4_segmentation": "off [fixed]", 
                "tx_ipxip6_segmentation": "off [fixed]", 
                "tx_lockless": "off [fixed]", 
                "tx_nocache_copy": "off", 
                "tx_scatter_gather": "on", 
                "tx_scatter_gather_fraglist": "off [fixed]", 
                "tx_sctp_segmentation": "off [fixed]", 
                "tx_tcp6_segmentation": "off [fixed]", 
                "tx_tcp_ecn_segmentation": "off [fixed]", 
                "tx_tcp_mangleid_segmentation": "off", 
                "tx_tcp_segmentation": "on", 
                "tx_udp_tnl_csum_segmentation": "off [fixed]", 
                "tx_udp_tnl_segmentation": "off [fixed]", 
                "tx_vlan_offload": "on [fixed]", 
                "tx_vlan_stag_hw_insert": "off [fixed]", 
                "udp_fragmentation_offload": "off [fixed]", 
                "vlan_challenged": "off [fixed]"
            }, 
            "hw_timestamp_filters": [], 
            "ipv4": {
                "address": "192.168.1.3", 
                "broadcast": "192.168.1.255", 
                "netmask": "255.255.255.0", 
                "network": "192.168.1.0"
            }, 
            "ipv6": [
                {
                    "address": "fe80::dc0f:6bff:feef:3c09", 
                    "prefix": "64", 
                    "scope": "link"
                }
            ], 
            "macaddress": "de:0f:6b:ef:3c:09", 
            "module": "e1000", 
            "mtu": 1500, 
            "pciid": "0000:00:12.0", 
            "promisc": false, 
            "speed": 1000, 
            "timestamping": [
                "tx_software", 
                "rx_software", 
                "software"
            ], 
            "type": "ether"
        }, 
        "ansible_env": {
            "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", 
            "HOME": "/home/justine", 
            "LANG": "fr_FR.UTF-8", 
            "LOGNAME": "justine", 
            "MAIL": "/var/mail/justine", 
            "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/games", 
            "PWD": "/home/justine", 
            "SHELL": "/bin/bash", 
            "SHLVL": "1", 
            "SSH_CLIENT": "192.168.1.208 50176 22", 
            "SSH_CONNECTION": "192.168.1.208 50176 192.168.1.3 22", 
            "SSH_TTY": "/dev/pts/1", 
            "TERM": "xterm-256color", 
            "USER": "justine", 
            "XDG_RUNTIME_DIR": "/run/user/1000", 
            "XDG_SESSION_ID": "450", 
            "_": "/bin/sh"
        }, 
        "ansible_fibre_channel_wwn": [], 
        "ansible_fips": false, 
        "ansible_form_factor": "Other", 
        "ansible_fqdn": "vm-deb-justine.u-pec.fr", 
        "ansible_hostname": "vm-deb-justine", 
        "ansible_hostnqn": "", 
        "ansible_interfaces": [
            "lo", 
            "ens18"
        ], 
        "ansible_is_chroot": false, 
        "ansible_iscsi_iqn": "", 
        "ansible_kernel": "4.9.0-8-amd64", 
        "ansible_lo": {
            "active": true, 
            "device": "lo", 
            "features": {
                "busy_poll": "off [fixed]", 
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "on", 
                "highdma": "on [fixed]", 
                "hw_tc_offload": "off [fixed]", 
                "l2_fwd_offload": "off [fixed]", 
                "large_receive_offload": "off [fixed]", 
                "loopback": "on [fixed]", 
                "netns_local": "on [fixed]", 
                "ntuple_filters": "off [fixed]", 
                "receive_hashing": "off [fixed]", 
                "rx_all": "off [fixed]", 
                "rx_checksumming": "on [fixed]", 
                "rx_fcs": "off [fixed]", 
                "rx_vlan_filter": "off [fixed]", 
                "rx_vlan_offload": "off [fixed]", 
                "rx_vlan_stag_filter": "off [fixed]", 
                "rx_vlan_stag_hw_parse": "off [fixed]", 
                "scatter_gather": "on", 
                "tcp_segmentation_offload": "on", 
                "tx_checksum_fcoe_crc": "off [fixed]", 
                "tx_checksum_ip_generic": "on [fixed]", 
                "tx_checksum_ipv4": "off [fixed]", 
                "tx_checksum_ipv6": "off [fixed]", 
                "tx_checksum_sctp": "on [fixed]", 
                "tx_checksumming": "on", 
                "tx_fcoe_segmentation": "off [fixed]", 
                "tx_gre_csum_segmentation": "off [fixed]", 
                "tx_gre_segmentation": "off [fixed]", 
                "tx_gso_partial": "off [fixed]", 
                "tx_gso_robust": "off [fixed]", 
                "tx_ipxip4_segmentation": "off [fixed]", 
                "tx_ipxip6_segmentation": "off [fixed]", 
                "tx_lockless": "on [fixed]", 
                "tx_nocache_copy": "off [fixed]", 
                "tx_scatter_gather": "on [fixed]", 
                "tx_scatter_gather_fraglist": "on [fixed]", 
                "tx_sctp_segmentation": "on", 
                "tx_tcp6_segmentation": "on", 
                "tx_tcp_ecn_segmentation": "on", 
                "tx_tcp_mangleid_segmentation": "on", 
                "tx_tcp_segmentation": "on", 
                "tx_udp_tnl_csum_segmentation": "off [fixed]", 
                "tx_udp_tnl_segmentation": "off [fixed]", 
                "tx_vlan_offload": "off [fixed]", 
                "tx_vlan_stag_hw_insert": "off [fixed]", 
                "udp_fragmentation_offload": "on", 
                "vlan_challenged": "on [fixed]"
            }, 
            "hw_timestamp_filters": [], 
            "ipv4": {
                "address": "127.0.0.1", 
                "broadcast": "host", 
                "netmask": "255.0.0.0", 
                "network": "127.0.0.0"
            }, 
            "ipv6": [
                {
                    "address": "::1", 
                    "prefix": "128", 
                    "scope": "host"
                }
            ], 
            "mtu": 65536, 
            "promisc": false, 
            "timestamping": [
                "rx_software", 
                "software"
            ], 
            "type": "loopback"
        }, 
        "ansible_local": {}, 
        "ansible_lsb": {
            "codename": "stretch", 
            "description": "Debian GNU/Linux 9.8 (stretch)", 
            "id": "Debian", 
            "major_release": "9", 
            "release": "9.8"
        }, 
        "ansible_machine": "x86_64", 
        "ansible_machine_id": "4a102f96174047ff8dfaaad49ccee1af", 
        "ansible_memfree_mb": 292, 
        "ansible_memory_mb": {
            "nocache": {
                "free": 683, 
                "used": 313
            }, 
            "real": {
                "free": 292, 
                "total": 996, 
                "used": 704
            }, 
            "swap": {
                "cached": 0, 
                "free": 1002, 
                "total": 1021, 
                "used": 19
            }
        }, 
        "ansible_memtotal_mb": 996, 
        "ansible_mounts": [
            {
                "block_available": 13416944, 
                "block_size": 4096, 
                "block_total": 15157979, 
                "block_used": 1741035, 
                "device": "/dev/sda1", 
                "fstype": "ext4", 
                "inode_available": 3746499, 
                "inode_total": 3866624, 
                "inode_used": 120125, 
                "mount": "/", 
                "options": "rw,relatime,errors=remount-ro,data=ordered", 
                "size_available": 54955802624, 
                "size_total": 62087081984, 
                "uuid": "e3ec661d-def0-4549-9627-ba6ddf0d15ab"
            }
        ], 
        "ansible_nodename": "vm-deb-justine", 
        "ansible_os_family": "Debian", 
        "ansible_pkg_mgr": "apt", 
        "ansible_proc_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-4.9.0-8-amd64", 
            "quiet": true, 
            "ro": true, 
            "root": "UUID=e3ec661d-def0-4549-9627-ba6ddf0d15ab"
        }, 
        "ansible_processor": [
            "0", 
            "GenuineIntel", 
            "Common KVM processor"
        ], 
        "ansible_processor_cores": 1, 
        "ansible_processor_count": 1, 
        "ansible_processor_threads_per_core": 1, 
        "ansible_processor_vcpus": 1, 
        "ansible_product_name": "Standard PC (i440FX + PIIX, 1996)", 
        "ansible_product_serial": "NA", 
        "ansible_product_uuid": "NA", 
        "ansible_product_version": "pc-i440fx-2.12", 
        "ansible_python": {
            "executable": "/usr/bin/python", 
            "has_sslcontext": true, 
            "type": "CPython", 
            "version": {
                "major": 2, 
                "micro": 13, 
                "minor": 7, 
                "releaselevel": "final", 
                "serial": 0
            }, 
            "version_info": [
                2, 
                7, 
                13, 
                "final", 
                0
            ]
        }, 
        "ansible_python_version": "2.7.13", 
        "ansible_real_group_id": 1000, 
        "ansible_real_user_id": 1000, 
        "ansible_selinux": {
            "status": "disabled"
        }, 
        "ansible_selinux_python_present": true, 
        "ansible_service_mgr": "systemd", 
        "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBD6CDpuGoWFchVwwsVX4hhOcveEJD7hqA9WWMTcO0injcRlSvxEehDlVuRoG+8h2mOumx6s4CuA3fthe7ZCE/xs=", 
        "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIDn2yv+4fLATLNDq9B3hMm1YlZHNYZZmwylNmrQLupOD", 
        "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDPslznquuniKvkFC2ACBP1TrwLeGQFzd7mjL3yRzjrKWSW1p4roTKbuK5zVymheuoWVPFWlJataTFuWzzYs0khQgSP2o5p6zOK6Luj7jD6Td5ueEONakBhS9z1LzLQgenyQdQO86uUdpRYvSRBPBkQNjNqEuC+Xwjii96JWvxGEu+V5TppFMjLfS/P3W62J1nQwcgcB0wK1AZXYaSSvC98TQw9qwNEUh48t7d/3fhLodDjRHIO3QaVXSnWDgdY+FMXTBArP3KaDDhmXQIiUsVxkFtRz7I3Zj3vJhQakuf3Cjn/dGIctXFRXT6dEFJF5TP6UKomurIyI5aBamUkR7kp", 
        "ansible_swapfree_mb": 1002, 
        "ansible_swaptotal_mb": 1021, 
        "ansible_system": "Linux", 
        "ansible_system_capabilities": [
            ""
        ], 
        "ansible_system_capabilities_enforced": "True", 
        "ansible_system_vendor": "QEMU", 
        "ansible_uptime_seconds": 1134249, 
        "ansible_user_dir": "/home/justine", 
        "ansible_user_gecos": "justine,,,", 
        "ansible_user_gid": 1000, 
        "ansible_user_id": "justine", 
        "ansible_user_shell": "/bin/bash", 
        "ansible_user_uid": 1000, 
        "ansible_userspace_architecture": "x86_64", 
        "ansible_userspace_bits": "64", 
        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "kvm", 
        "discovered_interpreter_python": "/usr/bin/python", 
        "gather_subset": [
            "all"
        ], 
        "module_setup": true
    }, 
    "changed": false
}


Fichiers d'inventaire

Les fichiers d'inventaire peuvent prendre deux formes : INI (la plus simple selon moi) et yaml.

À savoir : notation par crochets

Mettons que j'ai plusieurs machines apache : apache1, apache2, apache3... Je peux noter comme ça pour avoir les machines 1 à 3:

apache[1:3]

groupes avec variables de groupes

INI:

[servs]
192.168.1.1

[servs:vars]
new_name: host

YAML:

servs:
  hosts:
    host1:
  vars:
    new_name: hostname

Variables d'hôtes

INI

[targets]

localhost              ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_user=mpdehaan
other2.example.com     ansible_connection=ssh        ansible_user=mdehaan

YAML

atlanta:
  host1:
    http_port: 80
    maxRequestsPerChild: 808
  host2:
    http_port: 303
    maxRequestsPerChild: 909

Héritage

On peut faire des groupes de groupes avec le mot-clef "children". On peut ainsi faire hériter aux enfants des variables de leurs parents.

INI:

[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

YAML

all:
  children:
    usa:
      children:
        southeast:
          children:
            atlanta:
              hosts:
                host1:
                host2:
            raleigh:
              hosts:
                host2:
                host3:
          vars:
            some_server: foo.southeast.example.com
            halon_system_timeout: 30
            self_destruct_countdown: 60
            escape_pods: 2
        northeast:
        northwest:
        southwest:

Commandes Ad-Hoc

Les commandes Ad-Hoc sont parfois très utiles. Ci-dessous, un exemple simple utilisant un fichier d'inventaires (serv est le nom du groupe d'hôtes):

<syntaxhighlight lang='bash'> ansible serv -i inventaire.ini -a who -r -u ansible --key-file id_ansible ansible servs -i inventaire.ini -u ansible --key-file id_ansible --become -m raw -a "cat /var/log/apt/history.log"

  1. Syntaxe : ansible group -i inventaire [options] [module]

</syntaxhighlight>

-a sert à envoyer des commandes directement, du coup on ne fait pas de -m ici (même si c'est bien entendu possible).

Si je n'ai pas de fichier d'inventaire, je peux le construire à la main avec -i et préciser que je lance sur all (noter la virgule à la fin de la liste de machines) :

<syntaxhighlight lang='bash'> ansible all -i "machine1, machine2," [...] </syntaxhighlight>