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"
],