2022-10-24 13:31 Temps de lecture : 25 min

Guide de commandes Ansible Ad-hoc avec exemples

Les commandes *ad hoc* dans Ansible offrent la possibilité d'exécuter des opérations de manière instantanée, sans nécessiter leur sauvegarde pour une utilisation future. Cet article se concentre sur l'emploi des commandes *ad hoc* d'Ansible.

Nombre de tâches Ansible ne requièrent pas la création d'un *playbook* spécifique. L'exécution d'une commande *ad hoc* s'avère suffisante. Il s'agit de commandes en ligne unique qui permettent de mener à bien une action ponctuelle sur un hôte distant. Ces commandes se trouvent dans le répertoire `/usr/bin/ansible`.

Des opérations telles que la vérification de la disponibilité des hôtes par ping, la copie de fichiers, le redémarrage de serveurs ou l'installation de logiciels peuvent être accomplies aisément via les commandes *ad hoc* d'Ansible. Voici un aperçu des commandes *ad hoc* essentielles qu'il est utile de connaître.

Commandes Fondamentales

La commande *ad hoc* ci-dessous sollicite le module `ping` sur tous les hôtes répertoriés dans le fichier d'inventaire. L'option `-m` sert à spécifier le module à utiliser.

[email protected]:/home/toptips.fr# ansible all -m ping
node1 | SUCCÈS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

L'instruction ci-après utilise le module `setup` sur un groupe d'hôtes nommés "Client" présents dans le fichier d'inventaire `/etc/ansible/hosts`.

[email protected]:/home/toptips.fr# ansible Client -m setup -a "filter=ansible_distribution*"
node1 | SUCCÈS => {
    "ansible_facts": {
        "ansible_distribution": "Ubuntu",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/os-release",
        "ansible_distribution_file_variety": "Debian",
        "ansible_distribution_major_version": "18",
        "ansible_distribution_release": "cosmic",
        "ansible_distribution_version": "18.10",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

La commande ci-dessous permet de demander une authentification par mot de passe SSH. Pour ce faire, ajoutez l'option `--ask-pass` à la fin de la commande. Après son exécution, le système vous invitera à saisir votre mot de passe SSH.

[email protected]:/home/toptips.fr# ansible Client -m ping --ask-pass
Mot de passe SSH:
node1 | SUCCÈS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

La commande qui suit permet d'exécuter des instructions *ad hoc* en tant qu'utilisateur non root, tout en bénéficiant de privilèges root. L'option `--become` octroie ces privilèges et l'option `-K` sollicite le mot de passe.

[email protected]:/home/toptips.fr# ansible Client -m shell -a 'fdisk -l' -u toptips.fr --become -K
Mot de passe BECOME :
node1 | CHANGÉ | rc=0 >>
Disque /dev/loop0 : 14.5 Mio, 15208448 octets, 29704 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets


Disque /dev/loop2 : 42.1 Mio, 44183552 octets, 86296 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets


Disque /dev/loop3 : 149.9 Mio, 157184000 octets, 307000 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets


Disque /dev/loop5 : 140.7 Mio, 147501056 octets, 288088 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets


Disque /dev/loop6 : 151.2 Mio, 158584832 octets, 309736 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets


Disque /dev/loop7 : 14.8 Mio, 15458304 octets, 30192 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets


Disque /dev/sda : 500 Gio, 536870912000 octets, 1048576000 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets
Type d'étiquette de disque : dos
Identifiant de disque : 0xcef957f5

Périphérique  Amorce  Début        Fin    Secteurs Taille Id Type
/dev/sda1            2048  462639103 462637056 220.6G 83 Linux
/dev/sda2  *    462639104  464592895   1953792   954M 83 Linux
/dev/sda3       464592896  482168831  17575936   8.4G 82 Linux swap / Solaris
/dev/sda4       482168832 1048573951 566405120 270.1G 83 Linux


Disque /dev/loop8 : 4 Mio, 4218880 octets, 8240 secteurs
Unités : secteurs de 1 * 512 = 512 octets
Taille de secteur (logique/physique) : 512 octets / 512 octets
Taille d'E/S (minimale/optimale) : 512 octets / 512 octets

Cette commande *ad hoc* est employée pour redémarrer le système en utilisant l'option `-f` pour paramétrer le nombre de *forks*.

[email protected]:/home/toptips.fr# ansible Client -a "/sbin/reboot" -f 1

Transfert de Fichiers

La commande Ansible *ad hoc* qui suit permet de transférer un fichier d'une source vers une destination pour un groupe d'hôtes ("Client") défini dans le fichier d'inventaire. Une fois le mot de passe saisi, la sortie indiquera `change : true`, signalant ainsi le succès du transfert.

[email protected]:/home/toptips.fr# ansible Client -m copy -a 'src=/home/toptips.fr/nginx.yml dest=/home/toptips.fr/Desktop/ owner=root mode=0644' -u root --become -K
Mot de passe BECOME :
node1 | CHANGÉ => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "5631822866afd5f19b928edb3ba018385df22dd3",
    "dest": "/home/toptips.fr/Desktop/nginx.yml",
    "gid": 0,
    "group": "root",
    "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634",
    "mode": "0644",
    "owner": "root",
    "size": 280,
    "src": "/root/.ansible/tmp/ansible-tmp-1562253463.3-214622150088155/source",
    "state": "file",
    "uid": 0
}

Exécutez la commande ci-après pour vérifier si le module de copie a fonctionné correctement. Le fichier transféré doit se trouver dans le répertoire de destination précisé.

[email protected]:/home/toptips.fr# ls Desktop/
nginx.yml

Je crée un nouveau répertoire pour exécuter le module `fetch` lors de la prochaine instruction *ad hoc*.

[email protected]:/home/toptips.fr# mkdir example
[email protected]:/home/toptips.fr# ls
Desktop  Documents  example  examples.desktop  nginx_new.yml  nginx.yml

La commande Ansible *ad hoc* ci-dessous est utilisée pour récupérer un fichier d'un hôte spécifique. Dans cette instance, nous téléchargeons un fichier à l'aide du module `fetch` du serveur node1 vers une destination locale du nœud Ansible.

[email protected]:/home/toptips.fr# ansible node1 -m fetch -a 'src=/etc/sudoers.d/nginx.yml dest=/home/toptips.fr/example/ flat=yes'
node1 | SUCCÈS => {
    "changed": false,
    "checksum": "5631822866afd5f19b928edb3ba018385df22dd3",
    "dest": "/home/toptips.fr/example/nginx.yml",
    "file": "/etc/sudoers.d/nginx.yml",
    "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634"
}

Vérifiez la présence du fichier dans le répertoire de destination spécifié.

[email protected]:/home/toptips.fr# ls example
nginx.yml

Gestion des Logiciels

L'instruction ci-après installe Nginx sur un groupe d'hôtes ("Client") à l'aide du module `apt`.

[email protected]:/home/toptips.fr# ansible Client -m apt -a 'name=nginx state=latest' --become
node1 | SUCCÈS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "cache_update_time": 1562411227,
    "cache_updated": false,
    "changed": false
}

La commande suivante supprime Nginx du groupe d'hôtes ("Client") via le module `apt` et purge toutes les configurations associées.

[email protected]:/home/toptips.fr# ansible Client -m apt -a 'name=nginx state=absent purge=yes' --become
node1 | CHANGÉ => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "Lecture des listes de paquets…nConstruction de l'arbre des dépendances…nLecture des informations d'état…nLes paquets suivants ont été installés automatiquement et ne sont plus requis :n  libnginx-mod-http-geoip libnginx-mod-http-image-filtern  libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-streamn  nginx-common nginx-corenUtilisez « sudo apt autoremove » pour les supprimer.nLes paquets suivants seront SUPPRIMÉS :n  nginx*n0 mis à niveau, 0 nouvellement installé, 1 à supprimer et 241 non mis à niveau.nAprès cette opération, 44.0 Ko d'espace disque seront libérés.n(Lecture de la base de données… r(Lecture de la base de données… 5 %r(Lecture de la base de données… 10 %r(Lecture de la base de données… 15 %r(Lecture de la base de données… 20 %r(Lecture de la base de données… 25 %r(Lecture de la base de données… 30 %r(Lecture de la base de données… 35 %r(Lecture de la base de données… 40 %r(Lecture de la base de données… 45 %r(Lecture de la base de données… 50 %r(Lecture de la base de données… 55 %r(Lecture de la base de données… 60 %r(Lecture de la base de données… 65 %r(Lecture de la base de données… 70 %r(Lecture de la base de données… 75 %r(Lecture de la base de données… 80 %r(Lecture de la base de données… 85 %r(Lecture de la base de données… 90 %r(Lecture de la base de données… 95 %r(Lecture de la base de données… 100 %r(Lecture de la base de données… 180191 fichiers et répertoires actuellement installés.)rnSuppression de nginx (1.15.5-0ubuntu2.1) ...rn",
    "stdout_lines": [
        "Lecture des listes de paquets...",
        "Construction de l'arbre des dépendances...",
        "Lecture des informations d'état...",
        "Les paquets suivants ont été installés automatiquement et ne sont plus requis :",
        "  libnginx-mod-http-geoip libnginx-mod-http-image-filter",
        "  libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream",
        "  nginx-common nginx-core",
         "Utilisez « sudo apt autoremove » pour les supprimer.",
        "Les paquets suivants seront SUPPRIMÉS :",
        "  nginx*",
         "0 mis à niveau, 0 nouvellement installé, 1 à supprimer et 241 non mis à niveau.",
        "Après cette opération, 44.0 Ko d'espace disque seront libérés.",
        "(Lecture de la base de données ... ",
        "(Lecture de la base de données ... 5%",
        "(Lecture de la base de données ... 10%",
        "(Lecture de la base de données ... 15%",
        "(Lecture de la base de données ... 20%",
        "(Lecture de la base de données ... 25%",
        "(Lecture de la base de données ... 30%",
        "(Lecture de la base de données ... 35%",
        "(Lecture de la base de données ... 40%",
        "(Lecture de la base de données ... 45%",
        "(Lecture de la base de données ... 50%",
        "(Lecture de la base de données ... 55%",
        "(Lecture de la base de données ... 60%",
        "(Lecture de la base de données ... 65%",
        "(Lecture de la base de données ... 70%",
        "(Lecture de la base de données ... 75%",
        "(Lecture de la base de données ... 80%",
        "(Lecture de la base de données ... 85%",
        "(Lecture de la base de données ... 90%",
        "(Lecture de la base de données ... 95%",
        "(Lecture de la base de données ... 100%",
        "(Lecture de la base de données ... 180191 fichiers et répertoires actuellement installés.)",
        "Suppression de nginx (1.15.5-0ubuntu2.1) ..."
    ]
}

Gestion des Services

La commande Ansible *ad hoc* ci-dessous fait appel au module `service` pour démarrer Nginx sur l'hôte. La valeur de l'état doit être réglée sur "started".

[email protected]:/home/toptips.fr# ansible Client -m service -a 'name=nginx state=started enabled=yes' --become
node1 | SUCCÈS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "enabled": true,
    "name": "nginx",
    "state": "started",
    "status": {
        "ActiveEnterTimestamp": "Sam 2019-07-06 08:28:02 EDT",
        "ActiveEnterTimestampMonotonic": "31411371",
        "ActiveExitTimestampMonotonic": "0",
        "ActiveState": "active",
        "After": "sysinit.target system.slice systemd-journald.socket basic.target network.target",
        "AllowIsolate": "no",
        "AmbientCapabilities": "",
        "AssertResult": "yes",
        "AssertTimestamp": "Sam 2019-07-06 08:27:59 EDT",
        "AssertTimestampMonotonic": "27694868",
        "Before": "multi-user.target shutdown.target",
        "BlockIOAccounting": "no",
        "BlockIOWeight": "[not set]",
        "CapabilityBoundingSet": "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend",
        "CollectMode": "inactive",
        "ConditionResult": "yes",
        "ConditionTimestamp": "Sam 2019-07-06 08:27:59 EDT",
        "ConditionTimestampMonotonic": "27694867",
        "ConfigurationDirectoryMode": "0755",
        "Conflicts": "shutdown.target",
        "ControlGroup": "/system.slice/nginx.service",
        "ControlPID": "0",
        "ExecMainStartTimestamp": "Sam 2019-07-06 08:28:02 EDT",
        "ExecMainStartTimestampMonotonic": "31411353",
        "ExecMainStatus": "0",
        "ExecReload": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -g daemon on; master_process on; -s reload ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "ExecStart": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -g daemon on; master_process on; ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "ExecStartPre": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -t -q -g daemon on; master_process on; ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "ExecStop": "{ path=/sbin/start-stop-daemon ; argv[]=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid ; ignore_errors=yes ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "FailureAction": "none",
        "FileDescriptorStoreMax": "0",
        "FragmentPath": "/lib/systemd/system/nginx.service",
        "GID": "[not set]",
        "GuessMainPID": "yes",
        "IOAccounting": "no",
        "IOSchedulingClass": "0",
        "IOSchedulingPriority": "0",
        "IOWeight": "[not set]",
    }
}

Le module `service` est utilisé pour arrêter Nginx sur l'hôte. L'état prend la valeur "stopped".

[email protected]:/home/toptips.fr# ansible Client -m service -a 'name=nginx state=stopped' --become
node1 | CHANGÉ => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "name": "nginx",
    "state": "stopped",
    "status": {
        "ActiveEnterTimestamp": "Sam 2019-07-06 08:28:02 EDT",
        "ActiveEnterTimestampMonotonic": "31411371",
         "ActiveExitTimestampMonotonic": "0",
        "ActiveState": "active",
        "After": "sysinit.target system.slice systemd-journald.socket basic.target network.target",
        "AllowIsolate": "no",
        "AmbientCapabilities": "",
        "AssertResult": "yes",
        "AssertTimestamp": "Sam 2019-07-06 08:27:59 EDT",
        "AssertTimestampMonotonic": "27694868",
        "Before": "multi-user.target shutdown.target",
        "BlockIOAccounting": "no",
        "BlockIOWeight": "[not set]",
        "CPUAccounting": "no",
        "CPUQuotaPerSecUSec": "infinity",
        "CanReload": "yes",
        "CanStart": "yes",
        "CanStop": "yes",
        "CapabilityBoundingSet": "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend",
        "CollectMode": "inactive",
        "ConditionResult": "yes",
        "ConditionTimestamp": "Sam 2019-07-06 08:27:59 EDT",
        "ConditionTimestampMonotonic": "27694867",
        "ConfigurationDirectoryMode": "0755",
        "Conflicts": "shutdown.target",
        "ControlGroup": "/system.slice/nginx.service",
        "ControlPID": "0",
        "DefaultDependencies": "yes",
        "Delegate": "no",
        "Description": "A high performance web server and a reverse proxy server",
        "DevicePolicy": "auto",
        "Documentation": "man:nginx(8)",
        "DynamicUser": "no",
    }
}

Analyse du Système

La commande Ansible *ad hoc* qui suit sollicite un module shell pour vérifier l'espace disque disponible sur les partitions racine.

[email protected]:/home/toptips.fr# ansible Client -m shell -a 'df -h /dev/sda2' --become
node1 | CHANGÉ | rc=0 >>
Système de fichiers      Taille  Utilisé Disponible Uti% Monté sur
/dev/sda2       923M  113M  748M  14% /boot

Cette commande utilise un module shell pour vérifier la mémoire vive (RAM) disponible sur l'hôte.

[email protected]:/home/toptips.fr# ansible Client -m shell -a 'free -m' --become
node1 | CHANGÉ | rc=0 >>
              total        utilisé        libre      partagé              cache     disponible
Mem :            5101         854        2760              27                1487          3947
Swap :          8581           0        8581

Cette commande vérifie le temps de fonctionnement de chaque serveur en cours d'exécution.

[email protected]:/home/toptips.fr# ansible Client -a "uptime"
node1 | CHANGÉ | rc=0 >>
11:31:17 up 1 jour, 2:40, 2 utilisateurs, charge moyenne : 0,23, 0,05, 0,02

Collecte d'Informations

La commande Ansible *ad hoc* ci-dessous vous fournira l'ensemble des données relatives à votre système, y compris toutes les variables existantes.

[email protected]:/home/toptips.fr# ansible all -m setup
node1 | SUCCÈS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.17.0.1",
            "10.0.2.15"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::763e:c0b4:14df:b273"
        ],
        "ansible_apparmor": {
            "status": "enabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "12/01/2006",
        "ansible_bios_version": "VirtualBox",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-4.18.0-25-generic",
            "quiet": true,
            "ro": true,
            "root": "UUID=5f85d8b7-0ab2-48c9-9e6e-4ecfbcbdaa83",
            "splash": true
        },
        "ansible_date_time": {
            "date": "2019-07-07",
            "day": "07",
            "epoch": "1562525628",
            "hour": "14",
            "iso8601": "2019-07-07T18:53:48Z",
            "iso8601_basic": "20190707T145348850596",
            "iso8601_basic_short": "20190707T145348",
            "iso8601_micro": "2019-07-07T18:53:48.850697Z",
            "minute": "53",
            "month": "07",
            "second": "48",
            "time": "14:53:48",
            "tz": "EDT",
            "tz_offset": "-0400",
            "weekday": "Sunday",
            "weekday_number": "0",
            "weeknumber": "26",
            "year": "2019"
        },
        "ansible_default_ipv4": {
            "address": "10.0.2.15",
            "alias": "enp0s3",
            "broadcast": "10.0.2.255",
            "gateway": "10.0.2.2",
            "interface": "enp0s3",
            "macaddress": "08:00:27:68:64:9a",
            "mtu": 1500,
            "netmask": "255.255.255.0",
            "network": "10.0.2.0",
            "type": "ether"
        },
        "ansible_default_ipv6": {},
        "ansible_device_links": {
            "ids": {
                "sda": [
                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5"
                ],
                "sda1": [
                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part1"
                ],
                "sda2": [
                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part2"
                ],
                "sda3": [
                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part3"
                ],
Auteur
France

Rédacteur tech, guides pratiques et astuces numériques.